home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Programming / MuManual / Autodocs / mmu.doc < prev    next >
Text File  |  2000-05-13  |  123KB  |  3,620 lines

  1. TABLE OF CONTENTS
  2.  
  3. mmu.library/--Background--
  4. mmu.library/--Patches--
  5. mmu.library/ActivateException
  6. mmu.library/AddContextHook
  7. mmu.library/AddMessageHook
  8. mmu.library/AllocAligned
  9. mmu.library/AllocLineVec
  10. mmu.library/AttemptLockContextList
  11. mmu.library/AttemptLockMMUContext
  12. mmu.library/BuildIndirect
  13. mmu.library/CopyContextRegion
  14. mmu.library/CopyMapping
  15. mmu.library/CreateMMUContext
  16. mmu.library/CurrentContext
  17. mmu.library/DeactivateException
  18. mmu.library/DefaultContext
  19. mmu.library/DeleteMMUContext
  20. mmu.library/DMAInitiate
  21. mmu.library/DMATerminate
  22. mmu.library/DupMapping
  23. mmu.library/EnterMMUContext
  24. mmu.library/GetIndirect
  25. mmu.library/GetMapping
  26. mmu.library/GetMappingProperties
  27. mmu.library/GetMMUContextData
  28. mmu.library/GetMMUType
  29. mmu.library/GetPageProperties
  30. mmu.library/GetPageSize
  31. mmu.library/GetProperties
  32. mmu.library/LeaveMMUContext
  33. mmu.library/LockContextList
  34. mmu.library/LockMMUContext
  35. mmu.library/NewMapping
  36. mmu.library/PhysicalLocation
  37. mmu.library/PhysicalPageLocation
  38. mmu.library/RebuildTree
  39. mmu.library/RebuildTrees
  40. mmu.library/ReleaseMapping
  41. mmu.library/RemapSize
  42. mmu.library/RemContextHook
  43. mmu.library/RemMessageHook
  44. mmu.library/RunOldConfig
  45. mmu.library/SetBusError
  46. mmu.library/SetIndirect
  47. mmu.library/SetIndirectArray
  48. mmu.library/SetMappingProperties
  49. mmu.library/SetMMUContextData
  50. mmu.library/SetPageProperties
  51. mmu.library/SetProperties
  52. mmu.library/SetPropertiesMapping
  53. mmu.library/SetPropertyList
  54. mmu.library/SuperContext
  55. mmu.library/UnlockContextList
  56. mmu.library/UnlockMMUContext
  57. mmu.library/WithoutMMU
  58.  
  59. mmu.library/--Background--             mmu.library/--Background--
  60.  
  61.     PURPOSE
  62.     The mmu.library provides functions for MMU related operations
  63.     as write- or read-protecting certain areas of memory for a
  64.     given set of tasks, or marking memory regions as "swapped"
  65.     virtual memory support. It offers an abstraction level on top
  66.     of the actual MMU and a unified interface for MMU purposes.
  67.  
  68.     The MMU lib does NOT implement virtual memory, that's the purpose
  69.     of another library - the memory.library. There's no much reason why
  70.     any application except the memory.library and probably some debugging
  71.     tools should call this library directly. The memory.library functions
  72.     on top of this library should suffer for "all day purposes".
  73.  
  74.     The basic object administrated by this library is the "context". A
  75.     "context" is the software abstraction of a MMU translation tree, it
  76.     keeps the information of the status of memory. The mmu.library 
  77.     provides a "global" context that represents the MMU translation tree
  78.     for all tasks. It is build by the init code of the library either by
  79.     snooping the already existing MMU translation tree or by building an
  80.     own tree by looking at the available memory and expansion devices.
  81.  
  82.     Programs can build own contexts by using the MMU library functions and
  83.     may enter or leave the contexts generated in this way. Several tasks
  84.     may share one context, as they represent, for example, multiple 
  85.     "threads" of one single program. Thus, the notation used here is some-
  86.     how turned around: A "context" in the amiga world is called "process"
  87.     in unix, and a "task" or "process" in the amiga world is called a
  88.     "thread" usually.
  89.  
  90.     Tasks that do not enter an own context explicitly share the common
  91.     global context. Even though it is possible to change the global 
  92.     context, this technique should be used only by debugging tools as the
  93.     enforcer. It could, for example, mark unused areas of the memory as
  94.     well as the first 4K as "invalid".
  95.  
  96.     The MMU library provides two "hooks" for each context, the 
  97.     "bus error hook" and the "segmentation fault" hook. The first hook
  98.     is called if an access to an invalid memory location is detected, or
  99.     a write to a read-only memory area. The second is called if an access
  100.     to a memory page marked as "swapped out" is detected. It's part of
  101.     the service of the MMU library to keep these two access violations
  102.     apart.
  103.  
  104.     The default hooks call simply the exception handler of the running
  105.     task, which generates by default the well known "guru". It's up to
  106.     programs on top of the MMU library to setup useful hooks. An enforcer
  107.     like tool might set "bus error hook" to print some useful information
  108.     about the access violation, the memory.library will set the 
  109.     "segmentation fault" hook to swap in the memory in question.
  110.  
  111.     The hooks are really "low-level" routines and are executed in super-
  112.     visor mode, and therefore very limited in power.
  113.  
  114.     The library provides itself a ready-for-use hook function which
  115.     sends a message to a task to be specified and suspends the task
  116.     that caused the bus error until the message is replied.
  117.  
  118.     MMU trees are managed on two levels, a "software abstraction level"
  119.     which is comfortable and easy to use. Memory "properties" of large
  120.     regions of memory can be redefined quite easely with one single
  121.     call, but rebuilding the MMU table tree from this abstraction layer
  122.     is a lengthly operation and requires quite a lot of CPU power
  123.     not available in critical applications.
  124.     Therefore, a more "hardware based" approach is available which
  125.     modifies the existing MMU table "on the fly" and is therefore
  126.     rather fast. However, memory pages to be handled like this must
  127.     be marked with the MAPP_SINGLE property to tell the library to
  128.     build the MMU table in a special way to allow fast modification
  129.     and to bypass some possible optimizations (e.g. "early page
  130.     terminators" and "invalid descriptors not at page level").
  131.     Modifications on this level are never seen by the abstraction
  132.     level above and should be used only once the MMU tree is complete.
  133.  
  134.     If that is, too, not fast enough, the MMU library allows building
  135.     pages using "indirect descriptors". That is, the page property
  136.     flags are given by a true hardware descriptor you provide. This
  137.     makes code CPU specific, obviously, but has the advantage that
  138.     page properties can be modified by a single long word "poke" in
  139.     your program, and the proper ATC flush. This is almost "hardware
  140.     banging", with some support.
  141.  
  142.     This method has one important drawback, namely that the library
  143.     is no longer able to disable caching for DMA transfer to and from
  144.     this page. Hence, NEVER EVER access an indirect page by DMA.
  145.  
  146. mmu.library/--Patches--                mmu.library/--Patches--
  147.  
  148.     To perform its job, the mmu.library has to install a number of 
  149.     system patches. I tried avoid this as best as possible, but some
  150.     installations have to be done.
  151.  
  152.     The following patches are installed:
  153.  
  154.  
  155. exec/CacheControl:      Replaced partially by a function that guarantees
  156.             that the data cache remains off when the mmu.library
  157.             builds descriptors.
  158.  
  159. exec/ColdReboot:    Replaced partially by a function that removes the
  160.             mmu.library installed MMU trees. This is done to
  161.             restart the processor with a clean MMU setup.
  162.  
  163. exec/Alert:        Replaced partially. The Alert() replacement routine
  164.             will check whether the alert caused is fatal or not,
  165.             and will Disable() and unload the mmu.library 
  166.             installed MMU tree if this is the case. Since a
  167.             deadend alert will go over into a reset without
  168.             calling ColdReboot(), this must be done here 
  169.             separately to ensure that the machine restarts
  170.             properly.
  171.  
  172. exec/AddMem;        Adding memory with a MMU setup active would or would
  173.             not mean that the MMU table must be adjusted to
  174.             reflect the changes. This function should not be
  175.             called once the system is setup and running.
  176.             It is here patched to an Alert(). 
  177.             The original routine is not called because some
  178.             68040/68060 libraries modify the MMU table on their 
  179.             own in case this happens.
  180.             I don't think this routine is really required unless
  181.             on startup, but in case it is I will replace it
  182.             completely on demand.
  183.  
  184. exec/AddConfigDev:      Patched to an Alert() for just the same reason than
  185.             above.
  186.  
  187. exec/CachePreDMA:       Replaced completely by a MMU library routine that
  188.             disables copyback mode for non-aligned pages and
  189.             translates the logical address passed in to the
  190.             physical address, by means of the mmu.library 
  191.             public context.
  192.  
  193. exec/CachePostDMA:      Ditto. Replaced completely by the MMU.library.
  194.  
  195.     
  196.  
  197. mmu.library/CreateMMUContext               mmu.library/CreateContext               mmu.library/CreateMMUContext
  198.  
  199.     NAME
  200.     CreateMMUContext - Build a new MMU context.
  201.  
  202.     SYNOPSIS
  203.     context = CreateMMUContextA ( tags );
  204.     d0                   a0
  205.  
  206.     context = CreateMMUContext ( tag1, ... ); 
  207.  
  208.  
  209.     struct MMUContext * CreateMMUContextA ( struct TagItem *);
  210.  
  211.     struct MMUContext * CreateMMUContext ( Tag tag1, ... );
  212.     
  213.     FUNCTION
  214.     This function builds a new MMU context.
  215.  
  216.     INPUTS
  217.     tags    -   Tag items for the context to be created. 
  218.  
  219.     Currently defined tags are:
  220.  
  221.  
  222.     MCXTAG_COPY      -  build a copy of the context * passed in,
  223.                 if the pointer is NULL, build a copy of
  224.                 the global default context. (RECOMMENDED!)
  225.  
  226.                 If this tag item is not given, all context
  227.                 addresses will be marked as MAPP_BLANK. Most
  228.                 likely not what you want.
  229.  
  230.                 If you specify a different page size than that
  231.                 of the context you want to clone, you should
  232.                 specify the MCXTAG_ERRORCODE as well and study
  233.                 the return code carefully. The mmu library might
  234.                 have performed some rounding to fit the old
  235.                 table specifications into the new table layout.
  236.                 In worst case, this will make your new table
  237.                 unusable. It is therefore in general not a good
  238.                 idea to specify a page size larger than that of
  239.                 the cloned context. Even though the library 
  240.                 itself allocates all its internal structures
  241.                 aligned to "worst case" page sizes, this might
  242.                 not be true for external user programs.
  243.                 
  244.     MCXTAG_EXECBASE  -  allow accesses of AbsExecBase and all accesses to
  245.                 valid memory in the first page, even if this
  246.                 page in the MMU tree - the "zeropage" - is
  247.                 marked as invalid. This is an important feature
  248.                 if the mmu.library is used to implement an
  249.                 Enforcer type program. 
  250.                 Accesses will be emulated in software and are
  251.                 hence *slow*. They should be avoided, either by
  252.                 running Os 3.0 or better, or by using a tool like
  253.                 "MuMove4k".
  254.  
  255.                 AbsExecBase accesses are handled with highest
  256.                 priority and might be faster than the rest of the
  257.                 emulation, even faster than the Enforcer, even
  258.                 though they're still slower than "the real thing".
  259.                 It is not guaranteed that the library will really
  260.                 read AbsExecBase from location four, dependent on
  261.                 some internals, it might give you a cached copy
  262.                 instead. This means usually no problem since
  263.                 AbsExecBase must not change while the machine is
  264.                 up and running. 
  265.  
  266.                 This option defaults to TRUE.
  267.  
  268.                 For more quirks about the zeropage, read the
  269.                 MCXTAG_ZEROBASE tag documentation below.
  270.  
  271.     MCXTAG_BLANKFILL  - defines a ULONG word fill value for blank
  272.                 memory regions.
  273.             
  274.                 This ULONG is read by the CPU in case a program
  275.                 tries an access to "empty" memory regions. It
  276.                 defaults to 0L, but other values might be use-
  277.                 ful for debugging.
  278.  
  279.     MCXTAG_MEMORYATTRS- An exec memory attributes specifier to be used
  280.                 for allocating memory for the (hardware) MMU
  281.                 tables. Defaults to MEMF_PUBLIC, check 
  282.                 exec/memory.h for other possibilities.
  283.  
  284.     MCXTAG_PRIVATESUPER A boolean value, either TRUE or FALSE. If TRUE,
  285.                 build a private MMU supervisor table for this
  286.                 context, independent of the default supervisor
  287.                 Context. BE WARNED! This means specifically that
  288.                 possible modifications of the default supervisor
  289.                 context will not be carried over to your private
  290.                 supervisor table.
  291.                 Even if you pass in FALSE here, the library might
  292.                 still ignore your choice and build a private
  293.                 supervisor table anyways. This happens if the
  294.                 table layout you've chosen is different to the
  295.                 default table layout, making the user tree in-
  296.                 compatible to the default supervisor tree.
  297.                 
  298.     MCXTAG_ZEROBASE   - This option takes only effect if MCXTAG_EXECBASE
  299.                 is TRUE and the first page of the MMU table is
  300.                 invalid. This means that the MMU library will
  301.                 emulate accesses to valid memory in the first page
  302.                 which remains unavailable to implement an 
  303.                 "Enforcer" function. This tag provides a base 
  304.                 address to be used by the emulation as physical
  305.                 base address.
  306.                 This tag defaults to NULL meaning that the 
  307.                 library will redirect accesses to the true 
  308.                 zeropage, making it available temporarely, but
  309.                 any other memory location - provided it is page 
  310.                 aligned - can be specified here as well. This
  311.                 is important if the zero page gets remapped to
  312.                 a different location, and an Enforcer type 
  313.                 program is run later on. The zero page remapper
  314.                 should specify this tag to redirect accesses 
  315.                 transparently, even if an Enforcer type 
  316.                 application invalidates the zero page. Failing
  317.                 to do so would make the MMU library emulating
  318.                 the access to the incorrect, non-remapped memory 
  319.                 location. Since other programs might want to
  320.                 build a private MMU table with a different
  321.                 table size, it is *NOT* enough to align the
  322.                 remap destination of the zeropage to GetPageSize()
  323.                 boundaries, RemapSize() alignment is required!
  324.                 THIS IS AN ADVANCED FEATURE.
  325.  
  326.     MCXTAG_DISCACHEDES  A boolean tag item. If set to TRUE, the memory
  327.                 that keeps the descriptors is cache-inhibited.
  328.                 This works around some problems that appear if a
  329.                 program attempts to hack on the MMU itself. The
  330.                 mmu.library code has no problems with descriptors
  331.                 in non-cacheable memory. Note, however, that the
  332.                 memory will be only non-cacheable "as seen" from
  333.                 the context itself. It will *NOT* change the
  334.                 cache mode as seen from other contexts, even from
  335.                 the supervisor Context of the given Context. 
  336.  
  337.                 *HACKING THE MMU TABLES IS ILLEGAL*
  338.  
  339.     MCXTAG_LOWMEMORYLIMIT  Define a boundary in the zero page such that 
  340.                 accesses to addresses higher than this boundary 
  341.                 will be emulated in software. This is mainly for
  342.                 68060/68040 support under Os V37 and V38 where
  343.                 chip memory started at 0x400 inside the zero page.
  344.                 (NEW for V42)
  345.                 The MuLib checks the chip memory base address on
  346.                 startup and provides a useful default.
  347.  
  348.  
  349.     The next tag items define the MMU table layout. A logical address,
  350.     used as input for the MMU, consists of exactly 32 bits. These
  351.     bits are now split from the left to the right into groups to define
  352.     a "path" in the MMU tree. Each "level" of the MMU tree should be
  353.     considered as an array of pointers, pointing to the next lower
  354.     level of the tree. The nodes of the tree are contain the descriptors
  355.     that define how the address belonging to the path from the root to
  356.     this descriptor should be handled. For example, consider a three-
  357.     level tree with 7 bits for level A and B, 6 bits for level C and
  358.     12 bits for the page. The address 0x01feabcd would be used like this
  359.     to find an descriptor:
  360.  
  361.     hex 0x01feabcd is binary
  362.     
  363.     ----7--- ----7---- ---6--- ------12-------  bits 
  364.     0000 000|1 1111 11|10 1010| 1011 1100 1101
  365.     \_______/\________/\______/\_____________/
  366.         |    |    |       |
  367.         |    |    |       |
  368.         V    |    |       |
  369.     Index into level A of the MMU tree is 0, hence the first pointer
  370.     is read. The MMU obtains now another array of pointers, called
  371.     the level B. |    |       |
  372.              |    |       |
  373.              V    |       |
  374.         Index into level B of the MMU tree is 127. The MMU uses
  375.         the last pointer from the table obtained in the previous
  376.         step.     |       |
  377.                   |       |
  378.                   V       |
  379.             Index into level C of the MMU tree is 42. The MMU
  380.             uses, hence, the 42nd pointer of the array pointed
  381.             to by the 127th pointer of the level B array. This
  382.             is now the "page descriptor", defining the base
  383.             address for the next step.
  384.                       |
  385.                       |
  386.                       V
  387.     This is now finally the page offset, 0xbcd in this example. It
  388.     is added to the base address from the page descriptor in level C.
  389.     If the address is not "remapped", the base address would be
  390.     identically to the first 32-12 = 20 bits of the physically address.
  391.     
  392.  
  393.     MCXTAG_DEPTH      - Depth of the MMU tree to build. Defaults to
  394.                 the depth of the global public context.
  395.  
  396.                 Legal values are 1..4 for the 68020/68851 and
  397.                 the 68030, but the 68040/68060 supports only
  398.                 trees of depth 3.
  399.  
  400.     MCXTAG_LEVELABITS - Number of bits of the logical address that make
  401.                 up the level A of the MMU tree. 2^bits is the
  402.                 number of entries on this level of the tree.
  403.  
  404.                 The 68020/68851 and the 68030 support here
  405.                 values from 1..15, the only legal value for
  406.                 the 68040 and 68060 is 7. 
  407.  
  408.                 The MMU library will pick a reasonable and
  409.                 system dependent default for you if you don't
  410.                 specify this tag item.
  411.  
  412.     MCXTAG_LEVELBBITS - Number of bits for the level B of the MMU tree,
  413.                 unused if the depth is smaller than two.
  414.  
  415.                 Legal values are 1..15 for the 851 and 030, and
  416.                 7 as only possible value for the 040 and 060.
  417.  
  418.     MCXTAG_LEVELCBITS - Number of bits of the level C of the MMU tree,
  419.                 unused if the depth is smaller than three.
  420.  
  421.                 Arguments may range from 1..15 for the 851 and
  422.                 030, and must be either 5 or 6 for the 040 and
  423.                 060.
  424.  
  425.     MCXTAG_LEVELDBITS - Number of bits in the level D of the MMU tree,
  426.                 only used if the depth is four and therefore
  427.                 unused on the 040 and 060. 
  428.  
  429.                 Must range from 1..15.
  430.  
  431.     MCXTAG_PAGEBITS   - Number of bits to be used from the logical
  432.                 address as the page offset. 2^bits is the
  433.                 page size. 
  434.  
  435.                 Legal values are 8..15, giving 256 bytes up
  436.                 to 32K pages for the 68020/68851 and 68030, or
  437.                 12..13 defining 4K resp. 8K pages for the
  438.                 68040 and 68060. 
  439.  
  440.                 The default is the page size of the global 
  441.                 context.
  442.  
  443.     All the "..."BITS specifications MUST sum up to 32 since a logical
  444.     address consists of exactly 32 bits. You may leave out some or all 
  445.     of these tags, the MMU library will keep care of the rest and will
  446.     chose reasonable defaults for you.
  447.  
  448.  
  449.     MCXTAG_ERRORCODE -  pointer to a ULONG the MMU library will fill
  450.                 in with an error code in case building the
  451.                 MMU tree failed. It will be set to 0L if the
  452.                 function succeeds. The following error codes
  453.                 have been defined:
  454.  
  455.         CCERR_NO_FREE_STORE         -  the library went out of memory.
  456.         CCERR_INVALID_PARAMETERS -  the parameters specified by the 
  457.                     tags are invalid.
  458.         CCERR_UNSUPPORTED         -    the parameters are valid, but 
  459.                     not supported by the hardware.
  460.         CCERR_TRIMMED            -    the library performed some minor
  461.                     adjustments on the MMU table passed
  462.                     in for cloning. The cache modes
  463.                     might not be optimal due to some
  464.                     roudings that have to be performed,
  465.                     but the MMU table should work in
  466.                     general.
  467.  
  468.                     THIS IS NOT AN ERROR, you will get
  469.                     your new context.
  470.  
  471.         CCERR_UNALIGNED         -    the library had to perform heavy
  472.                     rouding in the MMU table passed
  473.                     in, it might be unusable. For 
  474.                     example, remapped pages were mis-
  475.                     aligned and due to the rounding
  476.                     accesses might go to wrong 
  477.                     locations. If you get this return
  478.                     code, you should possibly deallocate
  479.                     the new context and inform the user
  480.                     that the request could not be satis-
  481.                     fied.
  482.  
  483.                     Still, THIS IS NOT AN ERROR. You
  484.                     get a new context, but possibly an
  485.                     usuable one.
  486.  
  487.     RETURNS
  488.     NULL if the new context couldn't be created or a handle to the
  489.     new context, as parameter to all MMU library functions.
  490.  
  491.     NOTES
  492.     This call makes NOT the current task entering the new context,
  493.     you've to call EnterMMUContext() explicitly for that purpose.
  494.  
  495.     The context structure is not documented intentionally. It depends
  496.     on the implementation.
  497.  
  498.     BUGS
  499.  
  500.     SEE ALSO
  501.     DeleteMMUContext()
  502.  
  503.     BUGS
  504.  
  505. mmu.library/DeleteMMUContext           mmu.library/DeleteMMUContext
  506.     
  507.     NAME
  508.     DeleteMMUContext - delete an MMU context build with CreateMMUContext.
  509.  
  510.     SYNOPSIS
  511.     DeleteMMUContext ( context );
  512.                 a0
  513.  
  514.     void DeleteMMUContext ( struct MMUContext * );
  515.  
  516.     FUNCTION
  517.     This function deletes a context build with CreateMMUContext().
  518.  
  519.  
  520.     INPUTS   
  521.     A handle to the context to be deleted.
  522.  
  523.     RETURNS
  524.     nothing.
  525.  
  526.     NOTES
  527.     This call doesn't remove any task from the context, especially the
  528.     current task is NOT removed from the context. You've to call
  529.     LeaveMMUContext() before.
  530.  
  531.     Deleting a context with some tasks still in this context will
  532.     cause this function to guru.
  533.  
  534.     If your context was created with a private supervisor context
  535.     included, you must call this function only *once*, with the
  536.     user context created. It will automatically deallocate the
  537.     attached supervisor context as well.
  538.  
  539.     BUGS
  540.  
  541.     SEE ALSO
  542.     CreateMMUContext()
  543.  
  544. mmu.library/EnterMMUContext            mmu.library/EnterMMUContext
  545.  
  546.     NAME
  547.     EnterMMUContext - let a task enter a specific context.
  548.  
  549.     SYNOPSIS
  550.     context = EnterMMUContext( context , task );
  551.     d0                 a0       a1
  552.  
  553.     struct MMUContext * EnterMMUContext( struct MMUContext * , 
  554.                          struct Task * );
  555.  
  556.     FUNCTION
  557.     Add a given task to a context. This makes the MMU settings defined
  558.     by the context available for the task in question.
  559.  
  560.     INPUTS
  561.     context - the context to enter or NULL for the global context.
  562.     task    - a pointer to the task structure that should enter the
  563.           context.
  564.  
  565.     RETURNS
  566.     a handle to the context the task participated before or NULL if
  567.     this function failed. The task will stay in the last context used
  568.     in this case.
  569.  
  570.     NOTES
  571.     This call uses the tc_Switch() and tc_Launch() functions of the
  572.     task structure. What basically happens here is that these functions
  573.     are set to internal procedures that swap the context specific
  574.     MMU table or the global MMU in and flush the ATC of the MMU.
  575.  
  576.     This call may fail, check the return code for NULL - either due to
  577.     lack of memory or because the task is part of a protected context
  578.     the current task hasn't entered.
  579.  
  580.     If you want to use the tc_Switch() and tc_Launch() functions your-
  581.     self, you should install a task specific context hook, see 
  582.     AddContextHook().
  583.  
  584.     This function can be used to change the context of a task by
  585.     adding it to a new context. The task specific context switch and
  586.     launch hooks will be "carried over" to the new context, but all
  587.     other MMU specific exceptions are now the matter of the new context.
  588.  
  589.     BUGS
  590.  
  591.     SEE ALSO
  592.     LeaveMMUContext(), exec/tasks.h
  593.  
  594. mmu.library/LeaveMMUContext            mmu.library/LeaveMMUContext
  595.     
  596.     NAME
  597.     LeaveMMUContext - remove a given task from a context.
  598.  
  599.     SYNOPSIS
  600.     context = LeaveMMUContext( task );
  601.     d0              a1
  602.  
  603.     struct MMUContext * LeaveMMUContext( struct Task *);
  604.  
  605.     FUNCTION
  606.     The specified task leaves its context and enters the global context.
  607.  
  608.     INPUTS
  609.     task - the task that should leave a private context and enter the
  610.         global default context.
  611.  
  612.     RETURNS
  613.     the context the task was added to or NULL on failure.
  614.     Might be the global default context if the task did not enter any 
  615.     context.
  616.  
  617.     NOTES
  618.     It is safe to call this function even if the task wasn't added to
  619.     any context. The function returns the global context in this case.
  620.  
  621.     This function must be called to any task participating a given
  622.     context to be able to delete that context.
  623.  
  624.     This function is equivalent to EnterMMUContext(NULL,task). 
  625.  
  626.     This function makes use of the tc_Switch() and tc_Launch() functions
  627.     of the task structure to be able to set the MMU root pointer.
  628.  
  629.     Make sure that you check for failure. This call may return NULL if
  630.     the task entered a protected context the current task does not
  631.     participate or if switch and launch exceptions are in use.
  632.  
  633.     BUGS
  634.  
  635.     SEE ALSO
  636.     EnterMMUContext(), DeleteMMUContext(),  
  637.     RemContextHook(), exec/tasks.h
  638.  
  639. mmu.library/CurrentContext             mmu.library/CurrentContext
  640.  
  641.     NAME
  642.     CurrentContext - find out the current context of a task.
  643.  
  644.     SYNOPSIS
  645.     context = CurrentContext( task );
  646.     d0               a1
  647.  
  648.     struct MMUContext * CurrentContext( struct Task * );
  649.  
  650.     FUNCTION
  651.     This function is used to get a handle to the context the given
  652.     task is added to, or to return the context of the calling task.
  653.  
  654.     INPUTS
  655.     task - the address of the task structure you like to investigate
  656.     or NULL to get a handle to the currently active context.
  657.  
  658.     RETURNS
  659.     a handle to the context the given task is added to, the global
  660.     context if the task is not attached to any context or the
  661.     currently active context if the argument is NULL. 
  662.  
  663.     NOTES
  664.     This call fails only if the given task is part of a protected
  665.     context which is not shared by the current task. The NULL
  666.     argument is always safe.
  667.  
  668.     BUGS
  669.  
  670.     SEE ALSO
  671.     FindTask()
  672.  
  673. mmu.library/AddContextHook             mmu.library/AddContextHook
  674.  
  675.     NAME
  676.     AddContextHook - set an exception handler to a Context
  677.  
  678.     SYNOPSIS
  679.     hook = AddContextHookA ( tags );
  680.                   a0
  681.  
  682.     hook = AddContextHook ( tag1, ... );
  683.  
  684.     
  685.     struct ExceptionHook * AddContextHookA ( struct TagItem * );
  686.  
  687.     struct ExceptionHook * AddContextHook ( Tag tag1, ... );
  688.  
  689.     FUNCTION
  690.     This call installs an exception hook for a given context for
  691.     various exception types the MMU library can provide.
  692.  
  693.     INPUTS
  694.     tags    -   A taglist defining the type of the exception hook
  695.             to be added.
  696.  
  697.     Currently defined are:
  698.  
  699.     MADTAG_CONTEXT  -    The context to which this exception hook
  700.                 should be added. This MUST be given for
  701.                 "swapped" handlers. If it is left blank
  702.                 or set to NULL for segmentation fault
  703.                 handlers, you define a global segmentation
  704.                 fault handler.
  705.  
  706.     MADTAG_TASK    -    If the hook should be called only if a
  707.                 specific task is running, specify a pointer
  708.                 to the task structure here. 
  709.                 Warning! Adding too many task specific
  710.                 hooks slows things down unnecessary.
  711.                 Remember that a MMU Context may hold more
  712.                 than one task.
  713.                 This MUST be given for the switch and launch
  714.                 hooks.
  715.  
  716.     MADTAG_TYPE    -    Type of the exception hook to build. The
  717.                 following types are available:
  718.  
  719.         MMUEH_SEGFAULT  -    Called on segmentation fault, i.e. write to
  720.                 a write protected page or access of an
  721.                 invalid page. Most useful for "Enforcer"
  722.                 like tools.
  723.  
  724.     MMUEH_SWAPPED   -    Called on access for a "swapped out" page.
  725.                 Most useful to implement virtual memory.
  726.  
  727.     MMUEH_SWITCH    -    Called when the task looses the CPU.
  728.     MMUEH_LAUNCH    -    Called when the task gains the CPU.
  729.                 Remember that the tc_Switch() and tc_Launch()
  730.                 function pointers are no longer available
  731.                 if the task has been added to a MMUContext.
  732.  
  733.     MMUEH_PAGEACCESS -    Called whenever a MAPP_SINGLE page gets
  734.                 build by the context. This could be used to
  735.                 modify the MMU tree "on the fly" if 
  736.                 necessary, the required parameters are passed
  737.                 thru.
  738.  
  739.     MADTAG_CODE     -    A function pointer to the code to be called.
  740.                 This should be an assembly language function.
  741.                 It is called like this:
  742.  
  743.     Register a0     -    Pointer to the ExceptionData structure or
  744.                 the PageAccessData.
  745.     Register a1     -    loaded with the MADTAG_DATA provided data.
  746.     Register a4     -    Ditto.
  747.     Register a5     -    Pointer to the code itself.
  748.     Register a6     -    MMUBase. NOT A SCRATCH.
  749.  
  750.     Registers d0-d1/a0-a1/a4-a5 are scratches and are available for the
  751.     Exception handler. You *MUST* set the "Z" condition code and
  752.     clear d0 on exit in case you handled the exception. Details on
  753.     how to write an exception handler are in the "Exception.doc" file.
  754.  
  755.     MADTAG_DATA    -      Data to be loaded for the hook function.
  756.     MADTAG_NAME    -    A name for the hook. Currently unused.
  757.     MADTAG_PRI    -    A priority, ranging from -128...+127.
  758.                 Hooks of higher priorities are called first.
  759.  
  760.     RESULTS
  761.     A handle to the exception hook. Do not interpret this handle.
  762.     Or NULL on failure.
  763.  
  764.     NOTES
  765.     this call will be used by the high-level function AddMessageHook().
  766.     The global segmentation fault hook may be set by a debugging tool 
  767.     like the enforcer.
  768.  
  769.     The exception will not be activated, you need to call 
  770.     ActivateException() explicitly to make the library call it.
  771.  
  772.     Much more needs to be said about this function, see Exception.doc
  773.     for details about the exception handlers.
  774.  
  775.     BUGS
  776.  
  777.     SEE ALSO
  778.     RemContextHook(), AddMessageHook(), ActivateException(),
  779.     exec/interrupts.h, Exception.doc
  780.  
  781. mmu.library/RemContextHook             mmu.library/RemContextHook
  782.  
  783.     NAME
  784.     RemContextHook - remove an exception handler from a Context
  785.  
  786.     SYNOPSIS
  787.     RemContextHook( hook )
  788.              a1
  789.  
  790.     void RemContextHook( struct ExceptionHook * );
  791.  
  792.     FUNCTION
  793.     This function removes a previously installed context hook
  794.     from the hook list.
  795.  
  796.     INPUTS
  797.     The handle of the hook, as obtained by AddContextHook().
  798.  
  799.     RESULTS
  800.     none.
  801.  
  802.     NOTES
  803.     You must call DeactivateException() on your hook before you
  804.     remove it.
  805.     Be aware that the library will call the exec exception handler,
  806.     i.e. will generate a guru in case no exception handler is
  807.     available.
  808.  
  809.     SEE ALSO
  810.     AddContextHook(), DeactivateException(), exec/interrupts.h
  811. mmu.library/AddMessageHook             mmu.library/AddMessageHook
  812.  
  813.     NAME
  814.     AddMessageHook - install a high-level hook function.
  815.  
  816.     SYNOPSIS
  817.     hook = AddMessageHookA ( tags );
  818.                   a0
  819.  
  820.     hook = AddMessageHook ( tag1, ... );
  821.  
  822.  
  823.     struct ExceptionHook * AddMessageHookA ( struct TagItem * );
  824.  
  825.     struct ExceptionHook * AddMessageHook ( Tag tag1, ... );
  826.  
  827.     FUNCTION
  828.     Installs a high-level hook of the tag-given properties.
  829.     As soon as an exception of the requested type occurs, an exception 
  830.     message (see below) will be sent to the port. The task that caused 
  831.     the exception will be halted until the message gets replied.
  832.     BE WARNED: Message hooks perform only operation if task switching
  833.     is enabled and interrupts are allowed and the code failed in
  834.     User mode. They will just "drop thru" to the next handler if this 
  835.     is not the case.
  836.  
  837.     INPUTS
  838.     tags    -   A taglist defining the type of the exception hook
  839.             to be added.
  840.  
  841.     Currently defined are:
  842.  
  843.     MADTAG_CONTEXT   -    The context to which this exception hook
  844.                 should be added. This MUST be given.
  845.  
  846.     MADTAG_TASK     -    If the hook should be called only if a
  847.                 specific task is running, specify a pointer
  848.                 to the task structure here. 
  849.                 Warning! Adding too many task specific
  850.                 hooks slows things down unnecessary.
  851.                 Remember that a MMU Context may hold more
  852.                 than one task.
  853.  
  854.     MADTAG_TYPE     -    Type of the exception hook to build. The
  855.                 following types are available:
  856.  
  857.     MMUEH_SEGFAULT   -    Called on segmentation fault, i.e. write to
  858.                 a write protected page or access of an
  859.                 invalid page. Most useful for "Enforcer"
  860.                 like tools.
  861.  
  862.         MMUEH_SWAPPED    -    Called on access for a "swapped out" page.
  863.                 Most useful to implement virtual memory.
  864.  
  865.     MADTAG_CATCHERPORT  -   The port to sent the data to.
  866.     MADTAG_NAME        -    A name for the hook. Currently unused.
  867.     MADTAG_PRI        -    A priority, ranging from -128...+127.
  868.                 Hooks of higher priorities are called first.
  869.  
  870.     On an exception, the following message will be sent to the port:
  871.  
  872.     struct ExceptionMessage {
  873.         struct Message        exm_msg;
  874.         struct ExceptionData    exm_Data;
  875.     };
  876.  
  877.     For details about the ExceptionData structure, see Exception.doc.
  878.  
  879.     Once the message gets replied, the faulted task is restarted.
  880.  
  881.     RESULTS
  882.     a handle for the exception that must be passed back to 
  883.     RemMessageHook() for removal or NULL on failure.
  884.     Do not interpret this handle.
  885.     
  886.     NOTES
  887.     The handler must have been added to a context with EnterMMUContext()
  888.     before this function can be used. Unlike the AddContextHook() 
  889.     function, this DOES NOT work for "plain" tasks without a context.
  890.  
  891.     The hook must be activated with ActivateException() before it 
  892.     gets called.
  893.  
  894.     This function is used by the memory.library to install its
  895.     exception handler. The port will be in this case the port of
  896.     the swapper daemon that loads swapped out pages from disk.
  897.  
  898.     BUGS
  899.     
  900.     SEE ALSO
  901.     AddContextHook(), RemContextHook(), RemMessageHook(), 
  902.     ActivateException(), Exception.doc
  903.  
  904. mmu.library/RemMessageHook             mmu.library/RemMessageHook
  905.  
  906.     NAME
  907.     RemMessageHook  -   remove a high-level hook from a context.
  908.  
  909.     SYNOPSIS
  910.     RemMessageHook( handle );
  911.              a1
  912.  
  913.     void RemMessageHook( struct ExceptionHook * );
  914.  
  915.  
  916.     FUNCTION
  917.     This function removed a previously installed Message hook from
  918.     the hook list of the context.
  919.  
  920.     INPUTS
  921.     handle - a handle to the message hook as returned by the 
  922.         AddMessageHook function.
  923.  
  924.     RESULTS
  925.     none.
  926.  
  927.     NOTES
  928.     To remove a message hook safely, deactivate it first with
  929.     DeactivateException(), then tell the daemon to reply all 
  930.     exceptions of this hook, then remove it. 
  931.  
  932.     Not following these rules may cause deadlocks.
  933.     
  934.     BUGS
  935.     
  936.     SEE ALSO
  937.     AddMessageHook(), AddContextHook(), RemContextHook(),
  938.     DeactivateException(), Exception.doc
  939.  
  940. mmu.library/ActivateException          mmu.library/ActivateException
  941.  
  942.     NAME
  943.     ActivateException   -   enable an exception hook.
  944.  
  945.     SYNOPSIS
  946.     ActivateException( hook );
  947.                 a1
  948.  
  949.     void ActivateException( struct ExceptionHook * );
  950.  
  951.     FUNCTION
  952.     Activates a formerly installed exception hook, either a low
  953.     level context hook or a high-level message hook.
  954.     
  955.     RETURNS
  956.     
  957.     NOTES
  958.     Hooks of either kind must be activated before the mmu.library
  959.     will call them. Hooks are deactivated after creation and must
  960.     be deactivated before they get removed.
  961.     This call can be safely used within interrupts and from super-
  962.     visor mode.
  963.  
  964.     BUGS
  965.  
  966.     SEE ALSO
  967.     DeactivateException(), AddContextHook(), AddMessageHook(),
  968.     Exception.doc
  969.  
  970. mmu.library/DeactivateException        mmu.library/DeactivateException
  971.  
  972.     NAME
  973.     DeactivateException -   enable an exception hook.
  974.  
  975.     SYNOPSIS
  976.     DeactivateException( hook );
  977.                   a1
  978.  
  979.     void DeactivateException( struct ExceptionHook * );
  980.  
  981.     FUNCTION
  982.     Deactivates a formerly installed exception hook, either a low
  983.     level context hook or a high-level message hook, i.e. disables
  984.     it from being called.
  985.     
  986.     RETURNS
  987.     
  988.     NOTES
  989.     Hooks of either kind must be activated before the mmu.library
  990.     will call them. Hooks are deactivated after creation and must
  991.     be deactivated before they get removed.
  992.     This call can be safely used within interrupts and from super-
  993.     visor mode.
  994.  
  995.     BUGS
  996.  
  997.     SEE ALSO
  998.     ActivateException(), RemContextHook(), RemMessageHook(),
  999.     Exception.doc
  1000.  
  1001. mmu.library/GetPageSize                mmu.library/GetPageSize
  1002.  
  1003.     NAME
  1004.     GetPageSize - return the page size of a context.
  1005.  
  1006.     SYNOPSIS
  1007.     pagesz = GetPageSize( context );
  1008.     d0            a0
  1009.  
  1010.     ULONG GetPageSize( struct MMUContext * );
  1011.  
  1012.     FUNCTION
  1013.     This function returns the page size selected by the MMU library for
  1014.     the given context. Possible page sizes are limited by the hardware
  1015.     and cannot be adjusted from the outside. The page size is set up
  1016.     by the MMU library for the global public context, and it can be
  1017.     selected from the available page sizes for private MMUContexts, see
  1018.     CreateMMUContext().
  1019.  
  1020.     INPUTS
  1021.     context - a handle to the context to be investigated or NULL for
  1022.         the active context.
  1023.  
  1024.     RESULTS
  1025.     the page size in bytes or zero for failure.
  1026.  
  1027.     NOTES
  1028.  
  1029.     BUGS
  1030.  
  1031.     SEE ALSO
  1032.     CreateMMUContext()
  1033.  
  1034. mmu.library/RemapSize                  mmu.library/RemapSize
  1035.  
  1036.     NAME
  1037.     RemapSize - return the block size for memory remapping.
  1038.  
  1039.     SYNOPSIS
  1040.     remapsize = RemapSize( context );
  1041.     d0             a0
  1042.  
  1043.     ULONG RemapSize( struct MMUContext * );
  1044.  
  1045.     FUNCTION
  1046.     This function returns the smallest possible block size, and
  1047.     therefore the alignment restrictions, for remapping of memory that
  1048.     should be added to the exec memory pool. Since the MMU tables have
  1049.     to be placed in non-fragmented memory, certain alignment 
  1050.     restrictions for the memory blocks the MMU tables are placed in
  1051.     arise. 
  1052.     This harder aligment condition is only required for memory
  1053.     that is put into the exec free list, but as long as remapped
  1054.     memory is never returned from AllocMem, the page size is good 
  1055.     enough.
  1056.  
  1057.     INPUTS
  1058.     context - a handle to the context to be investigated or NULL for
  1059.         the active context.
  1060.  
  1061.     RESULTS
  1062.     the smallest admissable block size for memory returned by 
  1063.     AllocMem().
  1064.  
  1065.     NOTES
  1066.     The call will fail if the given context is protected, the result
  1067.     will be zero in this case.
  1068.  
  1069.     Even though the mmu.library does support memory remapping, this
  1070.     does not mean all other programs do. For example, remember that
  1071.     the inputs to the "MAPP_REMAPPED" pages is a physical page size,
  1072.     hence your program has to translate the logical address obtained
  1073.     by AllocMem() to a physical address at first. This can be done 
  1074.     with the PhysicalLocation() function.
  1075.     
  1076.     Additionally, DMA devices might or might not support memory
  1077.     remapping, just for the same reason: They require physical, not
  1078.     logical addresses. The MMU library provides a translation mechanism
  1079.     in form of the ChachePreDMA() and CachePostDMA() functions of
  1080.     ExecBase, but not all DMA device drivers call these functions
  1081.     properly. Certain patches might be made available for devices
  1082.     not following this rule.
  1083.  
  1084.     BUGS
  1085.     Adding remapped memory to the freelist is highly untested and
  1086.     not recommended because of the quirks of this mechanism.
  1087.  
  1088.     SEE ALSO
  1089.     PhysicalLocation(), GetPageSize(), exec/CachePreDMA(),
  1090.     DMAInitiate()
  1091.  
  1092. mmu.library/SetProperties             mmu.library/SetProperties
  1093.  
  1094.     
  1095.     NAME
  1096.     SetProperties - set memory attributes for a given logical range.
  1097.  
  1098.     SYNOPSIS
  1099.  
  1100.     result = SetPropertiesA( context, flags, mask, lower, size, tags);
  1101.     d0                a0      d1    d2     a1    d0    a2
  1102.  
  1103.     BOOL SetPropertiesA( struct MMUContext *, ULONG, ULONG, ULONG, ULONG,
  1104.                  struct TagItem *);
  1105.  
  1106.  
  1107.     result = SetProperties( context, flags, mask, lower, size, tag1, ...);
  1108.  
  1109.     BOOL SetProperties( struct MMUContext *, ULONG, ULONG, ULONG, ULONG,
  1110.                 Tag tag1, ...);
  1111.  
  1112.     FUNCTION
  1113.     This call sets attributes of a certain memory range of the
  1114.     software abstraction layer of the MMU tree, aligned to page 
  1115.     boundaries.
  1116.  
  1117.     INPUTS
  1118.     context - a handle to the context to modify or NULL for the active
  1119.         context.
  1120.  
  1121.     flags   - a binary flags field for the attributes to define. The
  1122.         following bits have been defined:
  1123.  
  1124.         MAPP_WRITEPROTECTED  -  The page will be write 
  1125.             protected. Writes to this area will cause a segmentation
  1126.             fault.
  1127.  
  1128.         MAPP_ROM         - Read only memory, writes tolerated.
  1129.             This is almost identically to MAPP_WRITEPROTECTED except
  1130.             that writes into this area will not cause a call of the
  1131.             segmentation fault handler. The library will filter them
  1132.             out.
  1133.             This property can be used to simulate a ROM in RAM and
  1134.             might be useful for kickstart remappers.
  1135.  
  1136.         MAPP_USED         -   The "used" bit of the pages
  1137.             will be set. The CPU will set this bit automatically
  1138.             as soon as the pages are accessed.
  1139.  
  1140.             This flag will turn on the "USED" bit in the hard-
  1141.             ware MMU bit. NOT setting this flag means that the
  1142.             USED bit in the hardware tree is preserved, regard-
  1143.             less of the mask value.
  1144.  
  1145.         MAPP_MODIFIED         -   The "modified" bit of the pages
  1146.             will be set. The CPU will set this bit automatically
  1147.             as soon as a write is performed to the page in question.
  1148.             DO NOT SET THIS BIT TOGETHER WITH MAPP_WRITEPROTECTED
  1149.             OR WITHOUT MAPP_USED or the CPU might hang. 
  1150.  
  1151.             This flag will turn on the "MODIFIED" bit in the hard-
  1152.             ware MMU bit. NOT setting this flag means that the
  1153.             MODIFIED bit in the hardware tree is preserved, regard-
  1154.             less of the mask value.
  1155.  
  1156.         MAPP_PRIVATE         -   The page will be marked invalid
  1157.             for all but the given contexts.
  1158.  
  1159.         MAPP_INVALID         -   The page will be marked as 
  1160.             invalid. Accessing it will invoke the bus error hook.
  1161.             User data can be provided for this property mode,
  1162.             provided you don't select MAPP_SINGLEPAGE or 
  1163.             MAPP_REPAIRABLE as well.
  1164.  
  1165.         MAPP_SWAPPED         -   The page will be marked as
  1166.             swapped out.
  1167.             A block ID *MUST* be provided for this property mode.
  1168.  
  1169.         MAPP_CACHEINHIBIT    -   The page will be marked as non-
  1170.             cacheable.
  1171.  
  1172.         MAPP_IMPRECISEEXECPTION -   The page will be marked as 
  1173.             "imprecise exception". MAPP_CACHEINHIBIT is mandatory
  1174.             in this case or this flag does nothing.
  1175.             Only available for the 68060, but does not harm for
  1176.             other MMUs.
  1177.  
  1178.         MAPP_NONSERIALIZED   -   The page will be marked as
  1179.             serialized. MAPP_CACHEINHIBIT is mandatory if this
  1180.             property is selected. 
  1181.             Only available for the 68040, but does not harm for
  1182.             other MMUs.
  1183.  
  1184.         MAPP_COPYBACK         -   The page will be marked as
  1185.             "copyback" instead of "writethrough". Generally re-
  1186.             commended since this is faster for the '40 and '60.
  1187.             Only available for 68040 and 68060, but does not harm
  1188.             if selected for other MMUs. MAPP_CACHINHIBIT MUST NOT
  1189.             be selected.
  1190.     
  1191.         MAPP_REMAPPED         -   Map the page to a different
  1192.             memory location. Parameters are given in the tag items.
  1193.  
  1194.             Even though this seems simple, remapping memory is
  1195.             full of quirks. Obviously, DMA devices and the MMU
  1196.             itself see the true physical addresses and not the
  1197.             logical addresses as filtered by the MMU. Therefore,
  1198.             adding remapped memory to the exec.library freelist
  1199.             will cause nothing than trouble and hard to trace
  1200.             disk faults and crashes as soon as this memory is
  1201.             used by a DMA device or the mmu.library itself.
  1202.             (Note that even though the library is supposed to
  1203.              support this, this is currently untested)
  1204.             Even though there *are* documented methods how to
  1205.             prepare a DMA transfer for remapped memory, USING
  1206.             these exec function calls is unfortunately the 
  1207.             exceptions. Therefore, this method is currently un-
  1208.             supported, by most (!really!) DMA device drivers. 
  1209.             Amongst the broken devices are the gvpscsi.device 
  1210.             and the cybscsi.device, to give just two examples.
  1211.  
  1212.             The omniscsi.device (the "Guru ROM") can be fixed
  1213.             with the MuOmniScsiPatch.
  1214.  
  1215.             If you really *MUST* remap public memory, then align
  1216.             it *AT LEAST* to the border given by RemapSize().   
  1217.             Just page alignment WILL NOT BE ENOUGH due to the way
  1218.             how the library works internally.   
  1219.  
  1220.             YOU HAVE BEEN WARNED!
  1221.             
  1222.         MAPP_SUPERVISORONLY  -   The page will be not available
  1223.             for user programs.
  1224.  
  1225.             NOTE: This mode is currently implemented using invalid 
  1226.             page descriptors for the user pages and is ignored
  1227.             when building supervisor tables. This method saves some
  1228.             space for the 68040 and 68060 and was the only way how
  1229.             it could be done for the 68030 and 68851 without using
  1230.             MMU tables twice as large.
  1231.  
  1232.         MAPP_USERPAGE0         -   Set user page attribute 0.
  1233.             This selects the user page attribute 0 for the 68040
  1234.             and 68060. "USER" DOES NOT MEAN YOU!
  1235.             The status of this bit appears on special pins of the
  1236.             CPU and might be required by some hardware, so don't    
  1237.             play with this. You should not change this bit, by no
  1238.             means.
  1239.  
  1240.         MAPP_USERPAGE1         -   Set user page attribute 1.
  1241.             This selects the user page attribute 0 for the 68040
  1242.             and 68060. See above for warnings.
  1243.  
  1244.         MAPP_GLOBAL         -   The pages are part of the
  1245.             global (public) memory. 
  1246.             You should not set this bit manually, it is under
  1247.             control of the library to optimize table flushes.
  1248.  
  1249.         MAPP_BLANK         -   Blank memory.
  1250.             The pages are mapped to one special area in RAM so
  1251.             erraneous reads and writes to these pages won't harm. 
  1252.             MAPP_BLANK should ONLY be used to mark special memory
  1253.             areas as "non-available" and un-handled by the hardware,
  1254.             nothing else. 
  1255.  
  1256.         MAPP_SHARED         -   Properties are identically to
  1257.             the public context.
  1258.             This tells the library to use the same properties as
  1259.             for the global context. However, MAPP_SHARED pages
  1260.             are not automatically updated when the global context
  1261.             changes, it's just a convenient way of saying "I want
  1262.             to uninstall my settings".
  1263.  
  1264.         MAPP_TRANSLATED        -   Under control of the TTx registers.
  1265.             NEVER SET THIS BIT YOURSELF.
  1266.             Pages with the "MAPP_TRANSLATED" bit set are under
  1267.             control of the "transparent translation registers" of
  1268.             the MMU and are "out of scope" for the mmu.library.
  1269.             Defining any properties for this domain will do nothing
  1270.             (or little, dependent on the TTx register configuration).
  1271.             A virtual memory program MUST NOT use virtual addresses
  1272.             which are transparently translated, this won't work.
  1273.             The mmu.library tries to be smart about the TTx registers
  1274.             and disables "unuseful" TTx settings itself.
  1275.  
  1276.         MAPP_INDIRECT         -   Map to a user provided page
  1277.             descriptor.
  1278.             The provided pages(s) are mapped by a user provided
  1279.             page descriptor. This page descriptor MUST BE aligned
  1280.             to a long word address, and it MUST BE a valid page
  1281.             descriptor for the MMU used.
  1282.  
  1283.             NEVER EVER attempt DMA, such as harddisk reads or
  1284.             writes to a memory domain marked as MAPP_INDIRECT.
  1285.  
  1286.             Due to some cache peculatities, the data might be
  1287.             incorrect and the result would be corrupt data.
  1288.  
  1289.             The library will be able to mark pages as non-cacheable
  1290.             if this is required for the DMA transfer, but this
  1291.             magic does not work for indirect pages.
  1292.  
  1293.             JUST DON'T DO THAT, MAPP_INIDIRECT is definitely an
  1294.             advanced feature.
  1295.  
  1296.         MAPP_BUNDLED         -   Map all pages in range to
  1297.             a single page in RAM.
  1298.  
  1299.             The main purpose of this function is to provide a
  1300.             MAPP_BLANK property with a user-selectable target
  1301.             page.
  1302.  
  1303.         MAPP_SINGLEPAGE         -   Make this page available for
  1304.             SetPageProperties().
  1305.  
  1306.             WARNING! Setting this bit shortcuts some optimizations
  1307.             the library might perform on the MMU table. The system
  1308.             may easely run out of memory if you select this
  1309.             property for "too many" pages. Use it with care, you
  1310.             have been warned!
  1311.  
  1312.         MAPP_REPAIRABLE         -   Inform the exception handler
  1313.             to provide write data and to allow pipeline fill.
  1314.  
  1315.             If this bit is set, the exception handler gets informed
  1316.             that you want to know the write data in case writes
  1317.             fail, or you want to provide the read data in case
  1318.             reads fail. The read/write data is available in the
  1319.             ExceptionData structure, read the exception handler
  1320.             documentation.
  1321.  
  1322.             This flag should be combined with MAPP_INVALID,
  1323.             MAPP_WRITEPROTECTED, MAPP_SWAPPED or 
  1324.             MAPP_SUPERVISORONLY
  1325.  
  1326.             However, this technique requires a lot of "trickery"
  1327.             and should be expected to be slow and to create
  1328.             sub-optimal and over-sized MMU tables. Use it with
  1329.             care, on as few pages as possible and only if your
  1330.             exception handler is "not on a hurry".
  1331.  
  1332.         MAPP_USERATTRIBUTE0  -   This is for your private use.
  1333.             This bit does not have any specific function, it is
  1334.             for your private use.
  1335.  
  1336.         MAPP_USERATTRIBUTE1  -   This is for your private use.
  1337.         MAPP_USERATTRIBUTE2
  1338.         MAPP_USERATTRIBUTE3
  1339.  
  1340.  
  1341.     mask    -   A bit mask of the attributes to be changed.
  1342.  
  1343.         Note that the hardware USED and MODIFIED bits will never
  1344.         be cleared, even though the properties say so and the
  1345.         corresponding bits in the mask are set. However, you can
  1346.         force them "ON" if you like, this saves unnecessary write-
  1347.         backs of the MMU.
  1348.     
  1349.     lower   -   The lower boundary of the logical address to be 
  1350.         modified. This must be aligned to the page size or this call
  1351.         will guru.
  1352.  
  1353.     size    -   Size of the region to be modified. Must be a multiple
  1354.         of the page size.
  1355.  
  1356.     tags    -   A tag array with additional data. Currently defined:
  1357.  
  1358.         MAPTAG_DESTINATION   -   the physical destination of the
  1359.             logical address. Must be provided for the MAPP_MAPPED
  1360.             or MAPP_BUNDLED bits. 
  1361.  
  1362.         MAPTAG_BLOCKID       -   a unique ID the MMU.library doesn't
  1363.             care about, for external usage of the memory.library.
  1364.             Must be provided for the MAPP_SWAPPED flag and may be
  1365.             used to indicate where on disk the swapped page is
  1366.             kept.
  1367.         
  1368.         MAPTAG_USERDATA      -   a unique cookie you might provide
  1369.             for MAPP_INVALID pages and which is passed thru to the
  1370.             segmentation fault exception handler.
  1371.  
  1372.         MAPTAG_DESCRIPTOR    -   a pointer to a long word aligned
  1373.             table descriptor for MAPP_INDIRECT.
  1374.         
  1375.  
  1376.     RESULTS
  1377.     A boolean success/failure indicator. Might fail if the context
  1378.     is protected or no memory is available for the modification.
  1379.  
  1380.     NOTES
  1381.     This call adjusts only the abstraction layer of the MMU table
  1382.     and marks the pages as "dirty". An explicit call to 
  1383.     RebuildTree() is required to make the changes active.
  1384.     You should bundle changes to the MMU table and call RebuildTree()
  1385.     once when you're done because rebuilding the MMU tree is a costy
  1386.     operation.
  1387.     If you need to modify the MMU table "on the fly" then consider
  1388.     using "SetPageProperties()", even though its use is restricted
  1389.     to single pages. Even faster are MAPP_INDIRECT pages, but - to
  1390.     say that again - DO NOT PERFORM DMA ON THESE PAGES.
  1391.  
  1392.     The page size can be read with GetPageSize(). 
  1393.  
  1394.     SUPERVISORONLY, SWAPPED and INVALID memory are implemented 
  1395.     using the same MMU attributes (invalid, namely), but the 
  1396.     library exception handler will filter them out and call 
  1397.     the appropriate hook.
  1398.  
  1399.     Write protection goes only for the context specified. It 
  1400.     usually makes sense to mark the memory region as PRIVATE as well, 
  1401.     unless you modify the public hook.
  1402.     (Note that MAPP_PRIVATE is currently not implemented because it
  1403.      will slow down things considerably.)
  1404.  
  1405.     You may freely mark the first memory page as INVALID provided
  1406.     the context MCXTAG_EXECBASE flag is set (it usually is).
  1407.     Long word read accesses to AbsExecBase will be filtered out by 
  1408.     the exception handler of the library and will be satisfied trans-
  1409.     parently to the program, as well as all other accesses except
  1410.     those into the first 1024 bytes.
  1411.  
  1412.     BUGS
  1413.  
  1414.     If the mask contains any property that requires user data, i.e.
  1415.     MAPP_REMAPPED or MAPP_SWAPPED, you *have* to redefine the user 
  1416.     data by tag items and MAY NOT leave them out, as the library 
  1417.     WILL NOT be able to restore the previously defined user data.
  1418.  
  1419.     SEE ALSO
  1420.     GetProperties(), AddContextHook(), GetPageSize(), 
  1421.     RemapSize(), RebuildTree(), SetPageProperties(),   
  1422.     SetMappingProperties()
  1423.  
  1424. mmu.library/SetPageProperties             mmu.library/SetPageProperties
  1425.  
  1426.     NAME
  1427.     SetPageProperties - set hardware memory attributes for a single
  1428.     page.
  1429.  
  1430.     SYNOPSIS
  1431.  
  1432.     result = SetPagePropertiesA( context, flags, mask, lower, tags);
  1433.     d0                a0    d1    d2    a1     a2
  1434.  
  1435.     BOOL SetPagePropertiesA( struct MMUContext *, ULONG, ULONG, ULONG,
  1436.                  struct TagItem *);
  1437.  
  1438.  
  1439.     result = SetPageProperties( context, flags, mask, lower, tag1, ...);
  1440.  
  1441.     BOOL SetPageProperties( struct MMUContext *, ULONG, ULONG, ULONG, 
  1442.                 Tag tag1, ...);
  1443.  
  1444.     FUNCTION
  1445.     This call sets the hardware attributes of a memory page.
  1446.  
  1447.     INPUTS
  1448.     context - a handle to the context to modify or NULL for the active
  1449.         context.
  1450.  
  1451.     flags   -   a binary flags field for the attributes to define. For
  1452.             the available attributes, see the SetProperties()
  1453.             function.
  1454.  
  1455.             Differences:
  1456.  
  1457.             MAPP_MODIFIED and MAPP_USED are really set or cleared
  1458.             in the true hardware table, the mask is considered
  1459.             correctly.
  1460.  
  1461.             Note that this function is the only method to clear
  1462.             these two hardware flags, SetProperties() or
  1463.             RebuildTree() don't do this.
  1464.  
  1465.     mask    -   a bit mask of all bits to be changed.
  1466.  
  1467.     tags    -   A tag array with additional data. Check 
  1468.             SetProperties() for details.
  1469.  
  1470.     RESULTS
  1471.     A boolean success/failure indicator. Might fail if the context
  1472.     is protected or no memory is available for the modification or
  1473.     the page is not marked with MAPP_SINGLEPAGE.
  1474.  
  1475.     NOTES
  1476.     BE WARNED! This function is very restricted in its use. It may well
  1477.     return FALSE even if all parameters are valid due to hardware 
  1478.     restrictions. This function does never ever rebuild an MMU tree,
  1479.     it just modifies "what is there". If the library choose to optimize
  1480.     the MMU library tree and to map a couple of pages by one descriptor,
  1481.     for what reasons ever, this call will fail. The details when this
  1482.     happens depends not only on the MMU, but on the general system
  1483.     layout.
  1484.  
  1485.     The ONLY documented way to get a mapping for a page that can be
  1486.     adjusted using this call is to set the page to MAPP_SINGLEPAGE using
  1487.     SetProperties() before.
  1488.  
  1489.     This call adjusts the hardware level of the MMU table if a descriptor 
  1490.     is available for a single page. It does not modify more than one
  1491.     page at once.
  1492.  
  1493.     It might happen that the library does not satisfy a request
  1494.     setting a page as "cacheable" if a DMA operation is currently in
  1495.     progress and the page must remain "nonacheable". However, the
  1496.     function will not fail in this case, but just delay the operation
  1497.     until the DMA is complete. The properties will always fall back to
  1498.     the next available option.
  1499.  
  1500.     This routine is safe to be called from within interrupts, it does
  1501.     not break any Forbid() or Disable() and is ideal for 
  1502.     quick-and-dirty repair operations within exceptions handlers,
  1503.     provided the MAPP_SINGLEPAGE flag has been set. 
  1504.  
  1505.     BUGS
  1506.     Note that MAPP_SINGLEPAGE is the flag you want here, not 
  1507.     MAPP_REPAIRABLE. That's something different!
  1508.  
  1509.     If the mask contains any property that requires user data, i.e.
  1510.     MAPP_REMAPPED or MAPP_SWAPPED, you *have* to redefine the user 
  1511.     data by tag items and MAY NOT leave them out, as the library 
  1512.     WILL NOT be able to restore the previously defined user data.
  1513.  
  1514.     SEE ALSO
  1515.         GetPageProperties(), AddContextHook(), 
  1516.         GetPageSize(), RebuildTree(), SetProperties(),
  1517.         SetMappingProperties()
  1518. mmu.library/RebuildTree                mmu.library/RebuildTree
  1519.  
  1520.     NAME    
  1521.     RebuildTree - build a MMU hardware tree from the software abstraction
  1522.     layer.
  1523.  
  1524.     SYNOPSIS
  1525.     result = RebuildTree( context );
  1526.     d0            a0
  1527.  
  1528.     BOOL RebuildTree ( struct MMUContext * );
  1529.  
  1530.     FUNCTION
  1531.     This function adjusts the MMU hardware tree to reflect the settings
  1532.     of the software abstraction layer defined with SetProperties().
  1533.  
  1534.     INPUTS
  1535.     context - a handle to the context to investigate or NULL for the
  1536.     active context.
  1537.  
  1538.     RESULTS
  1539.     a boolean success/failure indicator. TRUE if the operation was
  1540.     performed successfully.
  1541.  
  1542.     NOTES
  1543.     This is the big - and admittedly - slow one.
  1544.  
  1545.     Rebuilding the MMU tree is a relatively slow operation. The library
  1546.     tries to be smart about it and rebuilds only the pages whose
  1547.     mappings have been adjusted, but it's still a heavy beast.
  1548.  
  1549.     Properties temporarely defined with SetPageProperties() will be
  1550.     lost after the rebuild, except for the MAPP_USED and MAPP_MODIFIED
  1551.     bits.
  1552.  
  1553.     In case of failure, the hardware layer will remain valid and un-
  1554.     changed, but the context remains marked as "dirty".
  1555.  
  1556.     BE WARNED! A consistent use of the two flags is only possible
  1557.     if the pages are marked as MAPP_SINGLE. The page building algorithm
  1558.     does not guarantee consistent use of these two bits except for
  1559.     MAPP_SINGLE pages. Even though it *might* look well most the time,
  1560.     it is not documented that these two bits are kept correctly for non-
  1561.     SINGLE pages. If you need MODIFIED or USED page information, the only 
  1562.     way to get them is to mark these pages as MAPP_SINGLE. There's no 
  1563.     consistent use for these flags if early termination descriptors 
  1564.     (hence, w/o MAPP_SINGLE) are used by the library. 
  1565.  
  1566.     Even though some pages in the abstraction layer might be marked as
  1567.     un-USED or un-MODIFIED, this routine NEVER clears the hardware bits.
  1568.     It requires a call to SetPageProperties(), and hence the MAPP_SINGLE
  1569.     attribute (once again!) to do this.
  1570.  
  1571.     BUGS
  1572.     Much more should be said about this function.
  1573.  
  1574.     SEE ALSO
  1575.     SetProperties(), SetPageProperties(), GetProperties(),
  1576.     GetPageProperties(), RebuildTrees()
  1577.  
  1578. mmu.library/RebuildTrees              mmu.library/RebuildTrees
  1579.  
  1580.     NAME    
  1581.     RebuildTree - build a MMU hardware tree from the software abstraction
  1582.     layer for several contexts at once.                 (V41)
  1583.  
  1584.     SYNOPSIS
  1585.     result = RebuildTreesA( contextptrptr );
  1586.     d0                 a0
  1587.  
  1588.     result = RebuildTrees( context, context, ... );
  1589.  
  1590.  
  1591.     BOOL RebuildTreesA ( struct MMUContext ** );
  1592.  
  1593.     BOOL RebuildTrees ( struct MMUContext, ... ); 
  1594.  
  1595.     FUNCTION
  1596.     This function adjusts the MMU hardware tree to reflect the settings
  1597.     of the software abstraction layer defined with SetProperties().
  1598.  
  1599.     INPUTS
  1600.     contextptr - a pointer to a NULL terminated array of context
  1601.     handles.
  1602.  
  1603.     RESULTS
  1604.     a boolean success/failure indicator. TRUE if the operation was
  1605.     performed successfully and all context could have been rebuild.
  1606.  
  1607.     NOTES
  1608.     This is the big - and admittedly - slow one.
  1609.  
  1610.     Rebuilding the MMU tree is a relatively slow operation. The library
  1611.     tries to be smart about it and rebuilds only the pages whose
  1612.     mappings have been adjusted, but it's still a heavy beast.
  1613.  
  1614.     Properties temporarely defined with SetPageProperties() will be
  1615.     lost after the rebuild, except for the MAPP_USED and MAPP_MODIFIED
  1616.     bits.
  1617.  
  1618.     The advantage of this function is that it guarantees that all
  1619.     involved contexts remain unmodified and dirty in case one of the
  1620.     contexts cannot be rebuild. On success, it is guaranteed that all
  1621.     contexts will have been rebuild successfully.
  1622.  
  1623.     A special word has to be said about context locking here: This
  1624.     function will first call LockContextList(), and will then lock the
  1625.     individiual contexts in the order passed in. Hence, you've either
  1626.     to lock all contexts as well, and hence have to call 
  1627.     LockContextList() yourself as first step, or you must not lock any
  1628.     context of the contexts on the list. Everything else is dangerous
  1629.     and implies the risk of a deadlock.
  1630.  
  1631.     BE WARNED! A consistent use of the two flags is only possible
  1632.     if the pages are marked as MAPP_SINGLE. The page building algorithm
  1633.     does not guarantee consistent use of these two bits except for
  1634.     MAPP_SINGLE pages. Even though it *might* look well most the time,
  1635.     it is not documented that these two bits are kept correctly for non-
  1636.     SINGLE pages. If you need MODIFIED or USED page information, the only 
  1637.     way to get them is to mark these pages as MAPP_SINGLE. There's no 
  1638.     consistent use for these flags if early termination descriptors 
  1639.     (hence, w/o MAPP_SINGLE) are used by the library. 
  1640.  
  1641.     Even though some pages in the abstraction layer might be marked as
  1642.     un-USED or un-MODIFIED, this routine NEVER clears the hardware bits.
  1643.     It requires a call to SetPageProperties(), and hence the MAPP_SINGLE
  1644.     attribute (once again!) to do this.
  1645.  
  1646.     BUGS
  1647.     Much more should be said about this function.
  1648.  
  1649.     SEE ALSO
  1650.     SetProperties(), SetPageProperties(), GetProperties(),
  1651.     GetPageProperties(), RebuildTree()
  1652.  
  1653. mmu.library/GetProperties             mmu.library/GetProperties
  1654.  
  1655.     NAME
  1656.     GetProperties - read memory attributes for a given logical page
  1657.     from the MMU table abstraction layer.
  1658.  
  1659.     SYNOPSIS
  1660.  
  1661.     flags = GetPropertiesA( context, lower, tags);
  1662.     d0              a0      a1     a2
  1663.  
  1664.     ULONG GetPropertiesA( struct MMUContext *, void *, struct TagItem *);
  1665.  
  1666.  
  1667.     flags = GetProperties( context, lower, tag1, ...);
  1668.  
  1669.     ULONG GetProperties( struct MMUContext *, void *, Tag tag1, ...);
  1670.  
  1671.     FUNCTION
  1672.     This call reads the page properties of a certain address in
  1673.     memory from the software abstraction layer. It is the counterpart
  1674.     of SetProperties().
  1675.  
  1676.     INPUTS
  1677.     context - a handle to the context to investigate or NULL for the
  1678.         active context.
  1679.  
  1680.     lower   - the logical address of the page to investigate. The
  1681.         size of the page depends on the hardware and is selected by
  1682.         the MMU library. The number of bytes in a page is returned
  1683.         by GetPageSize().
  1684.  
  1685.     tags    - additional tags. Currently defined are:
  1686.  
  1687.         MAPTAG_DESTINATION  -   a pointer to a void * where 
  1688.             the physical destination of the logical address is
  1689.             filled in. Only available if the page is physically
  1690.             mapped to somewhere. Not filled in otherwise.
  1691.  
  1692.         MAPTAG_BLOCKID      -   read the a unique ID for the 
  1693.             MAPP_SWAPPED property. Untouched if the page isn't
  1694.             swapped. The tag data points to a long word which will
  1695.             be filled in for swapped out pages.
  1696.         
  1697.         MAPTAG_USERDATA     -   read the unique cookie for 
  1698.             INVALID pages, fill in the long word pointed to by
  1699.             the tag data field.
  1700.  
  1701.         MAPTAG_DESCRIPTOR   -   fill in the location of the
  1702.             indirect descriptor which is used to perform the
  1703.             mapping. Only used if MAPP_INDIRECT is used.
  1704.  
  1705.     RESULTS
  1706.     Returns a binary flags field for the attributes to define. See
  1707.     SetProperties() for details. Remember that MAPP_USED or 
  1708.     MAPP_MODIFIED reflect the bits on the abstraction layer, not the
  1709.     true hardware bits. You MUST call GetPageProperties() to read
  1710.     them, and hence *MUST* use MAPP_SINGLE pages.
  1711.  
  1712.     NOTES
  1713.     The page size can be read with GetPageSize(). Check the return  
  1714.     code of this call!
  1715.  
  1716.     The flags returned are valid for the given context, a different
  1717.     context may return a different flag setting and even a different
  1718.     physical locations.
  1719.  
  1720.     WARNING: The flags returned DO NOT reflect the hardware flags
  1721.     in the MMU table for the context. They DO reflect the settings
  1722.     installed with SetProperties() on the abstraction layer of the
  1723.     MMU tables.
  1724.  
  1725.     The hardware table might differ for the following reasons:
  1726.  
  1727.         - SetProperties() was called, but the changes haven't been
  1728.           made active with RebuildTree() yet.
  1729.         - A program modified the hardware layer directly using
  1730.           SetPageProperties().
  1731.         - DMA is currently active and the page in question has 
  1732.           therefore been marked as non-cacheable temporarely.
  1733.  
  1734.     Additionally, the library might have adjusted the abstraction
  1735.     layer itself by allocating non-cacheabe memory for its
  1736.     MMU tables.
  1737.  
  1738.     This routine is *NOT* safe to be called from within interrupts.
  1739.  
  1740.     BUGS
  1741.  
  1742.     SEE ALSO
  1743.     SetProperties(), AddContextHook(), GetMappingProperties(),
  1744.     GetPageSize(), GetPageProperties(), RebuildTree()
  1745.  
  1746. mmu.library/GetPageProperties         mmu.library/GetPageProperties
  1747.  
  1748.     
  1749.     NAME
  1750.     GetPropertiesA - read memory attributes from the hardware level
  1751.     for a given logical page. 
  1752.  
  1753.     SYNOPSIS
  1754.  
  1755.     flags = GetPagePropertiesA( context, lower, tags);
  1756.     d0                  a0       a1    a2
  1757.  
  1758.     ULONG GetPagePropertiesA( struct MMUContext *, void *, 
  1759.  
  1760.                 struct TagItem *);
  1761.  
  1762.  
  1763.     result = GetPageProperties( context, lower, tag1, ...);
  1764.  
  1765.     BOOL GetPageProperties( struct MMUContext *, void *, Tag tag1, ...);
  1766.  
  1767.     FUNCTION
  1768.     This call reads the page properties of a certain address in
  1769.     memory directly from the hardware. It is the counterpart
  1770.     of SetPageProperties().
  1771.  
  1772.     INPUTS
  1773.     context - a handle to the context to investigate or NULL for the
  1774.         active context. The library might use the MMU hardware directly
  1775.         if NULL is passed in, this call might be faster therefore.
  1776.  
  1777.     lower   - the logical address of the page to investigate. The
  1778.         size of the page depends on the hardware and is selected by
  1779.         the MMU library. The number of bytes in a page is returned
  1780.         by GetPageSize().
  1781.  
  1782.     tags    - additional tags. See GetProperties() for details.
  1783.  
  1784.  
  1785.     RESULTS
  1786.     Returns a binary flags field for the attributes to define. See
  1787.     SetProperties() for details.
  1788.  
  1789.     NOTES
  1790.     The page size can be read with GetPageSize(). 
  1791.  
  1792.     The flags returned are valid for the given context, a different
  1793.     context may return a different flag setting and even a different
  1794.     physical location.
  1795.  
  1796.     WARNING: The flags returned reflect the NOT the hardware flags
  1797.     in the MMU table for the context except for the MODIFIED and USED
  1798.     properties, even though the hardware level is *almost* consistent
  1799.     with these flags. 
  1800.  
  1801.     The hardware table might differ slightly in the following 
  1802.     situations:
  1803.  
  1804.         - DMA is currently active and the page in question has 
  1805.           therefore been marked as non-cacheable temporarely.
  1806.           Therefore, the cache settings returned are what will be
  1807.           re-installed here when DMA is finished. The library
  1808.           will "fake" the flags you have installed for the page
  1809.           investigated.
  1810.         - The library will use invalid descriptors to implement
  1811.           supervisor only or swapped pages.
  1812.  
  1813.     However, even though the flags might differ from the hardware
  1814.     flags, you're always safe to re-install the properties with
  1815.     SetPageProperties, there's no need to keep track of pecularities
  1816.     like cache disabling for DMA pages. The library does this for you.
  1817.  
  1818.     MAPP_MODIFIED and MAPP_USED are always read from the hardware
  1819.     directly.
  1820.  
  1821.     KEEP IN MIND that these two bits are only set and handled
  1822.     consistently for MAPP_SINGLE pages. You MUST NOT interpret
  1823.     them in all other cases, their values might get lost on a
  1824.     RebuildTree() call.
  1825.  
  1826.     This routine is safe to be called from within interrupts, most
  1827.     useful within exception handlers.
  1828.  
  1829.     BUGS
  1830.  
  1831.     SEE ALSO
  1832.         GetProperties(), AddContextHook(), 
  1833.         GetPageSize(), SetPageProperties(), RebuildTree()
  1834.  
  1835. mmu.library/AllocAligned                   mmu.library/AllocAligned
  1836.  
  1837.     NAME
  1838.     AllocAligned    -   allocate memory aligned to a memory border.
  1839.  
  1840.     SYNOPSIS
  1841.     mem = AllocAligned( bytesize, reqments, align );
  1842.     d0            d0     d1    a0
  1843.  
  1844.     void * AllocAligned( ULONG, ULONG, ULONG);
  1845.  
  1846.     FUNCTION
  1847.     Allocate memory aligned to certain boundaries.
  1848.  
  1849.     INPUTS
  1850.     bytesize - the size of the memory to allocate. 
  1851.  
  1852.     reqments -  exec style memory attributes
  1853.  
  1854.     align   -   the alignment restrictions of the page.
  1855.             MUST be a power of two.
  1856.  
  1857.     RETURNS
  1858.     a pointer to the allocated memory, aligned to the given border or
  1859.     NULL if no free physical memory could be found.
  1860.  
  1861.     NOTES
  1862.     Examples of how to use the "align" parameter:
  1863.  
  1864.     mem = AllocAligned(123,MEMF_PUBLIC|MEMF_CLEAR,1024);
  1865.  
  1866.     will allocate 123 bytes starting at a 1024 byte border, i.e. 
  1867.     the address returned will be divisible by 1024. The call will 
  1868.     clear the 123 bytes, NOT MORE.
  1869.  
  1870.     This is a service routine for the memory.library and shouldn't be
  1871.     used for all-day purposes.
  1872.  
  1873.     A DOS process will have its pr_Result2 field set to
  1874.     ERROR_NO_FREE_STORE if the memory allocation fails.
  1875.  
  1876.     The mmu.library calls this function by using its LVO library entry,
  1877.     so it can be patched to a smarter implementation if desired.
  1878.  
  1879.     BUGS
  1880.  
  1881.     SEE ALSO
  1882.     GetPageSize(), exec/memory.h
  1883.  
  1884. mmu.library/LockMMUContext             mmu.library/LockMMUContext
  1885.  
  1886.     NAME
  1887.     LockMMUContext      -   lock a MMU context
  1888.  
  1889.     SYNOPSIS
  1890.     LockMMUContext( context );
  1891.               a0
  1892.  
  1893.     void LockMMUContext( struct MMUContext * );
  1894.  
  1895.     FUNCTION
  1896.     Lock the software abstraction layer of the MMU table against
  1897.     modifications from other tasks.
  1898.  
  1899.     INPUTS
  1900.     A handle to a MMUContext or NULL for the active context.
  1901.  
  1902.     RETURNS
  1903.  
  1904.     NOTES
  1905.     This mechanism DOES NOT avoid changes of the MMU table on a lower
  1906.     level by SetPageProperties(), only SetProperties() from other
  1907.     tasks will be locked.
  1908.     Hence, it locks the abstraction layer, but not the hardware
  1909.     level.
  1910.  
  1911.     DO NOT lock more than one context at once, unless you locked
  1912.     also the context list with LockContextList(). Not following 
  1913.     this rule might cause deadlocks.
  1914.  
  1915.     BUGS
  1916.  
  1917.     SEE ALSO
  1918.     UnlockMMUContext(), SetPageProperties(), SetProperties(),
  1919.     LockContextList().
  1920.  
  1921. mmu.library/UnlockMMUContext           mmu.library/UnlockMMUContext
  1922.  
  1923.     NAME
  1924.     UnlockMMUContext    -   release a MMU context
  1925.  
  1926.     SYNOPSIS
  1927.     UnlockMMUContext( context );
  1928.                 a0
  1929.  
  1930.     void UnlockMMUContext( struct MMUContext * );
  1931.  
  1932.     FUNCTION
  1933.     Release the software abstraction layer of the MMU table, allow
  1934.     modifications from other tasks.
  1935.  
  1936.     INPUTS
  1937.     A handle to a MMUContext or NULL for the active context.
  1938.  
  1939.     RETURNS
  1940.  
  1941.     NOTES
  1942.     This mechanism DOES NOT avoid changes of the MMU table on a lower
  1943.     level by SetPageProperties(), only SetProperties() from other
  1944.     tasks will be locked.
  1945.     Hence, it locks the abstraction layer, but not the hardware
  1946.     level.
  1947.  
  1948.     BUGS
  1949.  
  1950.     SEE ALSO
  1951.     LockMMUContext(), SetPageProperties(), SetProperties(),
  1952.     AttemptLockMMUContext()
  1953.  
  1954. mmu.library/AttemptLockMMUContext      mmu.library/AttemptLockMMUContext
  1955.  
  1956.     NAME
  1957.     AttemptLockMMUContext       -   attempt to lock a MMU context
  1958.  
  1959.     SYNOPSIS
  1960.     ok = AttemptLockMMUContext( context );
  1961.                       a0
  1962.  
  1963.     struct MMUContext * AttemptLockMMUContext( struct MMUContext * );
  1964.  
  1965.     FUNCTION
  1966.     Grants non-blocking access to a MMU context.
  1967.     Attempts to lock the software abstraction layer of the MMU 
  1968.     table against modifications from other tasks. 
  1969.  
  1970.     INPUTS
  1971.     A handle to a MMUContext or NULL for the active context.
  1972.  
  1973.     RETURNS
  1974.     TRUE in case of success - the context is then locked for you
  1975.     and this lock must be released with UnlockMMUContext().
  1976.     FALSE in case any other task holds a lock.
  1977.  
  1978.     NOTES
  1979.     This mechanism DOES NOT avoid changes of the MMU table on a lower
  1980.     level by SetPageProperties(), only SetProperties() from other
  1981.     tasks will be locked.
  1982.     Hence, it locks the abstraction layer, but not the hardware
  1983.     level.
  1984.  
  1985.     DO NOT lock more than one context at once, unless you locked
  1986.     also the context list with LockContextList(). Not following 
  1987.     this rule might cause deadlocks.
  1988.  
  1989.     BUGS
  1990.     In pre-V39 machines, this call does not lock the context again
  1991.     in case you already hold a lock. This is a bug of the pre-V39
  1992.     AttemptSemaphore(), read the exec autodocs for a workaround.
  1993.  
  1994.     SEE ALSO
  1995.     UnlockMMUContext(), SetPageProperties(), SetProperties(),
  1996.     LockContextList(), AttemptSemaphore()
  1997.  
  1998. mmu.library/LockContextList            mmu.library/LockContextList
  1999.  
  2000.     NAME
  2001.     LockContextList     -   arbitrate a master lock.
  2002.  
  2003.     SYNOPSIS
  2004.     LockContextList( );
  2005.  
  2006.     void LockContextList( void );
  2007.  
  2008.     FUNCTION
  2009.     Arbitrates a master lock that allows locking more than one context
  2010.     at once to avoid deadlocks.
  2011.  
  2012.     INPUTS
  2013.  
  2014.     RETURNS
  2015.  
  2016.     NOTES
  2017.     This lock grants access for locking more than one context at once,
  2018.     to avoid deadlocks. I.e. in case you need to lock more than one
  2019.     context at a time, get this lock FIRST, then lock the contexts
  2020.     in any order you prefer.
  2021.  
  2022.     This call DOES NOT avoid modification of the context list or 
  2023.     individual contexts at all, i.e. other tasks are still able
  2024.     to create and to dispose contexts. To avoid this, you must lock
  2025.     the contexts afterwards.
  2026.  
  2027.     When you're done with the contexts, unlock the contexts first,
  2028.     THEN release this lock with UnlockContextList(). NOTE THE ORDER!
  2029.     
  2030.     BUGS
  2031.  
  2032.     SEE ALSO
  2033.     UnlockContextList(), LockMMUContext(), AttemptLockContextList()
  2034.  
  2035. mmu.library/UnlockContextList          mmu.library/UnlockContextList
  2036.  
  2037.     NAME
  2038.     UnlockContextList   -   release the master context lock
  2039.  
  2040.     SYNOPSIS
  2041.     UnlockContextList( );
  2042.  
  2043.     void UnlockContextList( void );
  2044.  
  2045.     FUNCTION
  2046.     Releases the master lock that allows locking more than one context
  2047.     at once to avoid deadlocks.
  2048.  
  2049.     INPUTS
  2050.  
  2051.     RETURNS
  2052.  
  2053.     NOTES
  2054.     This lock grants access for locking more than one context at once,
  2055.     to avoid deadlocks. I.e. in case you need to lock more than one
  2056.     context at a time, get this lock FIRST, then lock the contexts
  2057.     in any order you prefer.
  2058.  
  2059.     This call DOES NOT avoid modification of the context list or 
  2060.     individual contexts at all, i.e. other tasks are still able
  2061.     to create and to dispose contexts. To avoid this, you must lock
  2062.     the contexts afterwards.
  2063.  
  2064.     When you're done with the contexts, unlock the contexts first,
  2065.     THEN release this lock with UnlockContextList(). NOTE THE ORDER!
  2066.  
  2067.     BUGS
  2068.  
  2069.     SEE ALSO
  2070.     LockContextList(), LockMMUContext(), AttemptLockContextList()
  2071.  
  2072. mmu.library/AttemptLockContextList     mmu.library/AttemptLockContextList
  2073.  
  2074.     NAME
  2075.     AttemptLockContextList      -   attempt to arbitrate the master lock.
  2076.  
  2077.     SYNOPSIS
  2078.     ok = AttemptLockContextList( );
  2079.  
  2080.     LONG AttemptLockContextList( void );
  2081.  
  2082.     FUNCTION
  2083.     Attempts granting the context master lock in a non-blocking
  2084.     fashion. 
  2085.  
  2086.     INPUTS
  2087.  
  2088.     RETURNS
  2089.     TRUE in case the master lock could be arbitrated. You have then to
  2090.     release it with UnlockContextList().
  2091.     FALSE in case it is already locked and access could not be granted.
  2092.  
  2093.     NOTES
  2094.     This lock grants access for locking more than one context at once,
  2095.     to avoid deadlocks. I.e. in case you need to lock more than one
  2096.     context at a time, get this lock FIRST, then lock the contexts
  2097.     in any order you prefer.
  2098.  
  2099.     This call DOES NOT avoid modification of the context list or 
  2100.     individual contexts at all, i.e. other tasks are still able
  2101.     to create and to dispose contexts. To avoid this, you must lock
  2102.     the contexts afterwards.
  2103.  
  2104.     When you're done with the contexts, unlock the contexts first,
  2105.     THEN release this lock with UnlockContextList(). NOTE THE ORDER!
  2106.  
  2107.     BUGS
  2108.     In pre-V39 machines, this call does not lock the context again
  2109.     in case you already hold a lock. This is a bug of the pre-V39
  2110.     AttemptSemaphore(), read the exec autodocs for a workaround.
  2111.  
  2112.     SEE ALSO
  2113.     UnlockContextList(), LockMMUContext(), LockContextList(),
  2114.     AttemptLockSemaphore()
  2115.     
  2116. mmu.library/AllocLineVec               mmu.library/AllocLineVec
  2117.  
  2118.     NAME
  2119.     AllocLineVec    -   allocate cache line aligned, keep size
  2120.  
  2121.     SYNOPSIS
  2122.     AllocLineVec ( bytesize , attributes );
  2123.               d0          d1
  2124.  
  2125.     void * AllocLineVec ( ULONG, ULONG );
  2126.  
  2127.     FUNCTION
  2128.     Allocates memory like AllocVec(), but the memory is guaranteed
  2129.     to be aligned to cache lines of the processors in the system,
  2130.     even though the pointer returned IS NOT.
  2131.     Minimal guaranteed alignment is currently 32 bytes, i.e. a 
  2132.     PPC cache line. Future hardware may require stricter alignments.
  2133.  
  2134.     AllocLineVec'd memory is released with FreeVec() from the
  2135.     exec.library.
  2136.  
  2137.     INPUTS
  2138.     bytesize    -   the size of the memory block in bytes.
  2139.     attributes  -   memory attributes, see exec.library/AllocMem.
  2140.  
  2141.     RETURNS
  2142.     a pointer to the memory allocated or NULL on failure.
  2143.  
  2144.     A DOS process will have its pr_Result2 field set to
  2145.     ERROR_NO_FREE_STORE if the memory allocation fails.
  2146.  
  2147.     NOTES
  2148.     BIG WARNING: The pointer returned IS NEVER cache line aligned
  2149.     itself, but the complete memory block toghether with the
  2150.     vector size is kept in a cache line, regardless of the size
  2151.     passed in. Due to alignment restrictions, the routine might
  2152.     allocate a larger memory block than requested. It is however
  2153.     guaranteed that AT LEAST the size requested is returned, and
  2154.     that a FreeVec() will, indeed, free all memory.
  2155.  
  2156.     If MEMF_CLEAR is requested, the memory is cleared on the
  2157.     MC68K side, but the "zeros written" might be still in the
  2158.     cache. Hence, it is a good idea to flush the cache if the
  2159.     memory is passed over to the PPC.
  2160.  
  2161.     However, the vector size itself is always "pushed" to 
  2162.     memory, it is therefore guaranteed to be properly written
  2163.     back to the memory.
  2164.  
  2165.     The memory allocated this way is released by FreeVec() of
  2166.     the exec.library.
  2167.  
  2168.     BUGS
  2169.  
  2170.     SEE ALSO
  2171.     exec.library/AllocVec(), exec.library/FreeVec(), AllocLineVec()
  2172.  
  2173. mmu.library/PhysicalPageLocation       mmu.library/PhysicalPageLocation
  2174.  
  2175.     NAME
  2176.     PhysicalPageLocation    -   translate logical address to physical
  2177.  
  2178.     SYNOPSIS
  2179.     addr = PhysicalPageLocation( context , addr );
  2180.     d0                a0      a1
  2181.  
  2182.     void * PhysicalPageLocation( struct MMUContext * , void * );
  2183.  
  2184.     FUNCTION
  2185.     This function finds the physical address for the logical address
  2186.     passed in by scanning the MMU hardware table. 
  2187.     If the physical address is not available, NULL is returned.
  2188.  
  2189.     INPUTS
  2190.     context - the context to enter or NULL for the current context.
  2191.     addr    - the logical address to be translated.
  2192.  
  2193.     RETURNS
  2194.     the physical address of the logical address passed in, or NULL
  2195.     in case the logical address is not swapped in or otherwise out of
  2196.     control of the library.
  2197.  
  2198.     NOTES
  2199.     This is the low-level function, consider using the high-level
  2200.     function PhysicalLocation() when possible.
  2201.     This call can be safely used within interrupts.
  2202.  
  2203.     BUGS
  2204.     The function will also return NULL in case the logical address
  2205.     is translated to the address 0L. However, 0L should never be 
  2206.     used as physical address anyhow.
  2207.  
  2208.     SEE ALSO
  2209.     GetPageProperties(), PhysicalLocation()
  2210. mmu.library/PhysicalLocation           mmu.library/PhysicalLocation
  2211.  
  2212.     NAME
  2213.     PhysicalLocation    -   translate logical address to physical
  2214.  
  2215.     SYNOPSIS
  2216.     props = PhysicalLocation( context, addrptr, lenptr );
  2217.     d0                d1       a0       a1
  2218.  
  2219.     ULONG PhysicalLocation( struct MMUContext * , void ** , ULONG * );
  2220.  
  2221.     FUNCTION
  2222.     This function finds the physical address for the logical address
  2223.     passed in by scanning the software abstraction layer.
  2224.     If the physical address is not available, NULL is returned.
  2225.  
  2226.     INPUTS
  2227.     context - the context to enter or NULL for the current context.
  2228.     addrptr - points to the logical address to be translated.
  2229.           The physical address is filled in here, or NULL in case
  2230.           the logical address passed in is not available.
  2231.     lenptr  - Points to the length of the address range to be trans-
  2232.           lated. The function returns the length of the largest 
  2233.           possible continous memory range contained in the memory
  2234.           range passed in. Hence, this function may shorten the
  2235.           memory block for fragmentized memory models. It will
  2236.           NULL in case the memory is not available.
  2237.  
  2238.     RETURNS
  2239.     the properties of the memory range.
  2240.  
  2241.     NOTES
  2242.     This is the high-level function, it is not callable from within
  2243.     interrupts.
  2244.  
  2245.     In case you've to operate on a range of physical memory, start
  2246.     the translation with this call, then compare the size returned
  2247.     with the size of the memory block passed in. Because this 
  2248.     function may shorten the memory size in case the physical 
  2249.     memory is fragmentated, you should be prepared that the size
  2250.     returned is smaller than what was passed in. In this case, operate
  2251.     on the memory region returned, then add the returned size to
  2252.     the original logical address and call this function again to
  2253.     get the physical location of the next chunk.
  2254.  
  2255.     BUGS
  2256.     The function will also return NULL in case the logical address
  2257.     is translated to the address 0L. However, 0L should never be 
  2258.     used as physical address anyhow.
  2259.  
  2260.     SEE ALSO
  2261.     GetProperties(), PhysicalPageLocation()
  2262. mmu.library/DMAInitiate                mmu.library/DMAInitiate
  2263.  
  2264.     NAME
  2265.     DMAInitiate     -   start a DMA transport given a logical address.
  2266.  
  2267.     SYNOPSIS
  2268.     fine = DMAInitiate( context, addrptr, lenptr, write );
  2269.                  d1       a0     a1     d0
  2270.  
  2271.     BOOL DMAInitiate( struct MMUContext * , void ** , ULONG * , BOOL );
  2272.  
  2273.     FUNCTION
  2274.     This function finds the physical address for the logical address
  2275.     passed in by scanning a backup of the MMU translation tree.
  2276.     It ignores modifications made by the high-level and low-level
  2277.     functions unless RebuildTree() is called.
  2278.  
  2279.     INPUTS
  2280.     context - the context to enter or NULL for the current context.
  2281.           NOTE: This parameter is currently a dummy and should be
  2282.           set to NULL. The mmu.library will always use the public
  2283.           context for translation.
  2284.     addrptr - points to the logical address to be translated.
  2285.           The physical address is filled in here.
  2286.     lenptr  - Points to the length of the address range to be trans-
  2287.           lated. The function returns the length of the largest 
  2288.           possible continous memory range contained in the memory
  2289.           range passed in. Hence, this function may shorten the
  2290.           memory block for fragmentized memory models.
  2291.     write   - set this to TRUE for transports from a DMA device INTO
  2292.           the memory, i.e. device reads. Set this to FALSE for
  2293.           writes from memory to the device.
  2294.  
  2295.     RETURNS
  2296.     fine    - TRUE if the address and length passed in pointed to available
  2297.           memory. FALSE if the requested DMA transfer was invalid.
  2298.  
  2299.     The result code is new for V42, do not check it for V41 or below.
  2300.  
  2301.     NOTES
  2302.     The function checks whether the memory range passed in is available
  2303.     for DMA. It will guru in case it is not, i.e. the page is either
  2304.     swapped out, invalid, indirect, or write protected for
  2305.     DMA device reads. Reads into ROM addresses are silently tolerated,
  2306.     and, hence, are translations to and from blank dummy pages.
  2307.  
  2308.     This function is callable from within interrupts, but does only
  2309.     use a backup of the high-level table for its translation.
  2310.     Changes to the software abstraction level are not visible for
  2311.     this function unless RebuildTree() is called. Changes to the
  2312.     hardware level are not at all visible to this (and all other
  2313.     high-level) functions.
  2314.  
  2315.     In case you've to operate on a range of physical memory, start
  2316.     the translation with this call, then compare the size returned
  2317.     with the size of the memory block passed in. Because this 
  2318.     function may shorten the memory size in case the physical 
  2319.     memory is fragmentated, you should be prepared that the size
  2320.     returned is smaller than what was passed in. With the physical
  2321.     address returned, start the DMA and call DMATerminate() when
  2322.     done.
  2323.     In case the returned size is smaller than the block passed in,
  2324.     add the returned size to the original logical address and 
  2325.     call this function again to get the physical location of the 
  2326.     next chunk.
  2327.  
  2328.     EACH CALL TO DMAInitiate() must be matched by ONE AND PRECISELY
  2329.     ONE call to DMATerminate().
  2330.  
  2331.     Even though this function does not require locking the context, 
  2332.     I highly recommend doing so. It won't crash if you don't, but
  2333.     someone else could modify the MMU translation table in between.
  2334.     The library can deal with that, but the result of the DMA 
  2335.     operation might be different than what you expect.
  2336.  
  2337.     The pre-V42 releases did not return a result code but generated
  2338.     an alert in case illegal memory has been passed in. This changed
  2339.     for V42. DO NOT assume a meaningful result code for V41 or
  2340.     below.
  2341.  
  2342.     BUGS
  2343.     This function should really use the context passed in, but
  2344.     since most (if not all) DMA device drivers do not keep the 
  2345.     context of the task that actually initiated the transfer and
  2346.     hence would use the wrong context anyhow, DMA is currently limited
  2347.     to the public context.
  2348.  
  2349.     SEE ALSO
  2350.     DMATerminate(), PhysicalPageLocation(), exec/CachePreDMA()
  2351. mmu.library/DMATerminate               mmu.library/DMATerminate
  2352.  
  2353.     NAME
  2354.     DMATerminate    -   end a DMA transfer initiated by DMAInitiate.
  2355.  
  2356.     SYNOPSIS
  2357.     DMATerminate( context );
  2358.             d1       
  2359.  
  2360.     void DMATerminate( struct MMUContext * );
  2361.  
  2362.     FUNCTION
  2363.     This function ends a DMA transfer initiated by DMAInitate. It
  2364.     releases the resources by the first call.
  2365.  
  2366.     INPUTS
  2367.     context - the context to enter or NULL for the current context.
  2368.           NOTE: This parameter is currently a dummy and should be
  2369.           set to NULL. The mmu.library will always use the public
  2370.           context for translation.
  2371.  
  2372.     RETURNS
  2373.  
  2374.     NOTES
  2375.     This function is callable from within interrupts, but does only
  2376.     use a backup of the high-level table for its translation.
  2377.     Changes to the software abstraction level are not visible for
  2378.     this function unless RebuildTree() is called. Changes to the
  2379.     hardware level are not at all visible to this (and all other
  2380.     high-level) functions.
  2381.  
  2382.     EACH CALL TO DMAInitiate() must be matched by ONE AND PRECISELY
  2383.     ONE call to DMATerminate().
  2384.  
  2385.     For details, check the DMAInitiate() function.
  2386.  
  2387.     BUGS
  2388.     This function should really use the context passed in, but
  2389.     since most (if not all) DMA device drivers do not keep the 
  2390.     context of the task that actually initiated the transfer and
  2391.     hence would use the wrong context anyhow, DMA is currently limited
  2392.     to the public context.
  2393.  
  2394.     SEE ALSO
  2395.     DMAInitiate(), PhysicalPageLocation(), exec/CachePostDMA()
  2396. mmu.library/GetMapping                 mmu.library/GetMapping
  2397.  
  2398.     NAME
  2399.     GetMapping  -   get access to the memory map of a MMUContext
  2400.  
  2401.     SYNOPSIS
  2402.     list = GetMapping( context );
  2403.     d0             a0
  2404.  
  2405.     struct MinList * GetMapping( struct MMUContext * );
  2406.  
  2407.     FUNCTION
  2408.     This function makes a copy of the MapNodes for the given context.
  2409.     The nodes in this list describe the memory map as seen from tasks
  2410.     attached to this context, sorted by logical addresses.
  2411.     The list must be released afterwards with ReleaseMapping().
  2412.  
  2413.     INPUTS
  2414.     context - the context to enter or NULL for the current context.
  2415.  
  2416.     RETURNS
  2417.     a pointer to a struct MinList which contains the MapNodes for this
  2418.     context, sorted by physical address, or NULL in case of failure.
  2419.  
  2420.     NOTES
  2421.     The nodes are just a copy of the real nodes within the context.
  2422.     
  2423.     This function is most useful to make a backup of the context
  2424.     memory map before altering it. In case any of the modifications
  2425.     fail, you are able to undo all modifications completely with
  2426.     a call to SetPropertyList() - which can't fail. 
  2427.  
  2428.     To give an example:
  2429.  
  2430.     /* make a backup of the context how it looks now */
  2431.  
  2432.     LockMMUContext(ctx);
  2433.  
  2434.     if (list=GetMapping(ctx)) {
  2435.         fine=TRUE;
  2436.  
  2437.         /* Try to alter it, step by step. */
  2438.  
  2439.         if (!SetProperties(...)) 
  2440.         fine=FALSE;
  2441.  
  2442.         if (!SetProperties(...))
  2443.         fine=FALSE;
  2444.  
  2445.         /* etc, etc.... */
  2446.  
  2447.         /* Oops, we failed! Re-install the old setup. */
  2448.         if (!fine) 
  2449.         SetPropertyList(ctx,list);
  2450.     }
  2451.     
  2452.     ReleaseMapping(ctx,list);
  2453.     UnlockMMUContext(ctx);
  2454.     /* and so on... */
  2455.  
  2456.     Note that you've still to call ReleaseContextList(), even in
  2457.     case of failure when you've already re-installed backup property
  2458.     list.
  2459.  
  2460.     BUGS
  2461.  
  2462.     SEE ALSO
  2463.     ReleaseMapping(), SetPropertyList(), mmu/context.h
  2464. mmu.library/ReleaseMapping             mmu.library/ReleaseMapping
  2465.  
  2466.     NAME
  2467.     ReleaseMapping  -   get access to the memory map
  2468.  
  2469.     SYNOPSIS
  2470.     ReleaseMapping( context , list );
  2471.              a0    a1
  2472.  
  2473.     void ReleaseMapping( struct MMUContext * , struct MinList * );
  2474.  
  2475.     FUNCTION
  2476.     This function releases the list of MapNodes arbitrated by 
  2477.     GetMapping.
  2478.  
  2479.     INPUTS
  2480.     context - the context the nodes where taken from.
  2481.     list    - the backup property list to release.
  2482.  
  2483.     RETURNS
  2484.  
  2485.     NOTES
  2486.     This function *MUST* be called, even in case the property list
  2487.     was re-installed with SetPropertyList().
  2488.  
  2489.     BUGS
  2490.  
  2491.     SEE ALSO
  2492.     NewMapping(), GetMapping(), SetPropertyList()
  2493.  
  2494. mmu.library/NewMapping                 mmu.library/NewMapping
  2495.  
  2496.     NAME
  2497.     NewMapping      -   build a new memory map
  2498.  
  2499.     SYNOPSIS
  2500.     list = NewMapping ( );
  2501.     d0
  2502.  
  2503.     struct MinList * NewMapping ( void );
  2504.  
  2505.     FUNCTION
  2506.     Build and initialize a new memory map list. All addresses in this
  2507.     list will be marked as MAPP_BLANK.
  2508.  
  2509.     INPUTS
  2510.     nothing.
  2511.  
  2512.     RESULTS
  2513.     a MinList structure, initialized with MapNodes representing a
  2514.     completely blank memory layout or NULL on failure. You either need 
  2515.     to copy the layout from a context with CopyContextRegion(), or 
  2516.     define your own layout with calls to SetMappingProperties().
  2517.  
  2518.     NOTES
  2519.     Don't forget to release the list (and its contents) with 
  2520.     ReleaseMapping() when you're done.
  2521.  
  2522.     BUGS
  2523.  
  2524.     SEE ALSO
  2525.     CopyContextRegion(), SetMappingProperties(), ReleaseMapping(),
  2526.     GetMapping()
  2527.  
  2528. mmu.library/CopyMapping                mmu.library/CopyMapping
  2529.  
  2530.     NAME
  2531.     CopyMapping     -   transfer memory properties between lists
  2532.  
  2533.     SYNOPSIS
  2534.     fine = CopyMapping ( from , to , base , length , mask );
  2535.     d0              a0    a1    d0      d1      d2     
  2536.  
  2537.  
  2538.     BOOL CopyMapping ( struct MinList * , struct MinList * ,
  2539.  
  2540.                  ULONG , ULONG , ULONG );
  2541.  
  2542.     FUNCTION
  2543.     Copy the memory properties from one memory map to another, thru
  2544.     a mask.
  2545.  
  2546.     INPUTS
  2547.     from    -   the memory map which is (partially) to be transfered.
  2548.     to      -   the destination of the copy operation.
  2549.     base    -   base address. Memory properties will be copied starting
  2550.             at this address.
  2551.     length  -   length of the memory region in bytes whose properties
  2552.             shall be transfered.
  2553.     mask    -   a mask of property bits which are to be transfered. A
  2554.             zero bit in this mask indicates that the corresponding
  2555.             property in the destination will not be touched. For
  2556.             all the properties, check the SetProperties() function.
  2557.  
  2558.     RESULTS
  2559.     a boolean success/failure indicator. It is TRUE in case the 
  2560.     operation was performed, FALSE otherwise. The destination will
  2561.     not have been touched at all in this case.
  2562.  
  2563.     NOTES
  2564.     this call does not copy memory. It just copies memory attributes
  2565.     from one memory map to another.
  2566.  
  2567.     Check CopyContextRegion() to copy the properties from a context
  2568.     instead from a list.
  2569.  
  2570.     Since this call is not context based, the library will not be able
  2571.     to perform checks for correct page alignment, you have to do that
  2572.     yourself. Especially, note that SetPropertyList() - which attaches
  2573.     a memory map to a context - does not perform any check on this
  2574.     list either. Hence, *NOT* checking for page alignment here might
  2575.     result in an invalid context if you try to attach an incorrectly
  2576.     aligned list to a context later on. 
  2577.  
  2578.     BUGS
  2579.  
  2580.     SEE ALSO
  2581.     SetPropertyList(), ReleaseMapping(), DupMapping(), SetProperties(),
  2582.     CopyContextRegion()
  2583.  
  2584. mmu.library/DupMapping                 mmu.library/DupMapping
  2585.  
  2586.     NAME
  2587.     DupMapping      -   make a one-to-one copy of a memory map
  2588.  
  2589.     SYNOPSIS
  2590.     dup = DupMapping ( list );
  2591.     d0            a0
  2592.  
  2593.     struct MinList * DupMapping( struct MinList * );
  2594.  
  2595.     FUNCTION
  2596.     this call builds an identical copy of the memory map passed in.
  2597.  
  2598.     INPUTS
  2599.     list    -   the memory map to be copied.
  2600.  
  2601.     RESULTS
  2602.     another memory list, identical to the list passed in, or NULL on
  2603.     failure.
  2604.  
  2605.     NOTES
  2606.     Don't forget to release the memory list with ReleaseMapping()
  2607.     if you're done with it. You need to release both, the original as
  2608.     well as the duplicate.
  2609.     In case you want to make a copy of the memory map of a context,
  2610.     use GetMapping() instead.
  2611.  
  2612.     BUGS
  2613.  
  2614.     SEE ALSO
  2615.     GetMapping(), ReleaseMapping()
  2616.  
  2617. mmu.library/CopyContextRegion          mmu.library/CopyContextRegion
  2618.  
  2619.     NAME
  2620.     CopyContextRegion   -   transfer properties from a context to a list
  2621.  
  2622.     SYNOPSIS
  2623.     fine = CopyContextRegion ( ctx, list, base, length, mask );
  2624.     d0                a0   a1    d0    d1      d2
  2625.  
  2626.     BOOL CopyContextRegion ( struct MMUContext *, struct MinList *,
  2627.                  
  2628.                  ULONG, ULONG, ULONG );
  2629.  
  2630.     FUNCTION
  2631.     Copy the properties of a memory region defined by a context to 
  2632.     another memory map, thru a mask.
  2633.  
  2634.     INPUTS
  2635.     ctx     -   source context whose memory map shall be transfered.
  2636.     list    -   the destination memory map which is to be altered.
  2637.     base    -   base address of the memory region whose properties are
  2638.             to be copied.
  2639.     length  -   length of the memory region in bytes whose properties
  2640.             will be transfered.
  2641.     mask    -   a mask of property bits, see the SetProperties() 
  2642.             function for a detailed explanation. A zero bit in this
  2643.             mask means that the corresponding property in the 
  2644.             destination will be left alone and will remain unchanged.
  2645.  
  2646.     RESULTS
  2647.     a boolean success/failure indicator, TRUE for success. On failure,
  2648.     the destination memory map will not have been touched at all.
  2649.  
  2650.     NOTES
  2651.     This call does not copy memory at all, it just defines the memory
  2652.     properties of a given memory map from that of a given context.
  2653.  
  2654.     Check CopyMapping() to transport memory properties from one list
  2655.     to another.
  2656.  
  2657.     Since this call is not context based, the library will not be able
  2658.     to perform checks for correct page alignment, you have to do that
  2659.     yourself. Especially, note that SetPropertyList() - which attaches
  2660.     a memory map to a context - does not perform any check on this
  2661.     list either. Hence, *NOT* checking for page alignment here might
  2662.     result in an invalid context if you try to attach an incorrectly
  2663.     aligned list to a context later on. 
  2664.  
  2665.     BUGS
  2666.  
  2667.     SEE ALSO
  2668.     SetPropertyList(), ReleaseMapping(), SetProperties(),
  2669.     SetPropertiesMapping()
  2670.  
  2671. mmu.library/SetPropertiesMapping           mmu.library/SetPropertiesMapping
  2672.  
  2673.     NAME
  2674.     SetPropertiesMapping    -   transfer properties from a map list 
  2675.                     to a context
  2676.  
  2677.     SYNOPSIS
  2678.     fine = SetPropertiesMapping ( ctx, list, base, length, mask );
  2679.     d0                a0   a1    d0     d1      d2
  2680.  
  2681.     BOOL SetPropertiesMapping ( struct MMUContext *, struct MinList *,
  2682.                  
  2683.                  ULONG, ULONG, ULONG );
  2684.  
  2685.     FUNCTION
  2686.     Copy the properties of a memory map to a context, thru a mask.
  2687.     This is equivalent to SetProperties(), except that the source
  2688.     data is contained in a memory map instead given as function
  2689.     arguments. This function is reverse to CopyContextRegion().
  2690.  
  2691.     INPUTS
  2692.     ctx     -   destination context whose memory map shall be set.
  2693.     list    -   the source memory map, containing the data to be 
  2694.             transfered.
  2695.     base    -   base address of the memory region whose properties are
  2696.             to be copied.
  2697.     length  -   length of the memory region in bytes whose properties
  2698.             will be transfered.
  2699.     mask    -   a mask of property bits, see the SetProperties() 
  2700.             function for a detailed explanation. A zero bit in this
  2701.             mask means that the corresponding property in the 
  2702.             destination will be left alone and will remain unchanged.
  2703.  
  2704.     RESULTS
  2705.     a boolean success/failure indicator, TRUE for success. On failure,
  2706.     the destination context will not have been touched at all.
  2707.  
  2708.     NOTES
  2709.     This call does not copy memory at all, it just defines the memory
  2710.     properties of the context passed in.
  2711.  
  2712.     Check CopyMapping() to transport memory properties from one list
  2713.     to another, or CopyContextRegion() to transfer properties from a
  2714.     context to a list (the other direction).
  2715.  
  2716.     The library will not be able to perform checks for correct page 
  2717.     alignment, you have to do that yourself. 
  2718.     BUGS
  2719.  
  2720.     SEE ALSO
  2721.     SetPropertyList(), ReleaseMapping(), SetProperties(),
  2722.     CopyContextRegion()
  2723.  
  2724. mmu.library/SetMappingProperties      mmu.library/SetMappingProperties
  2725.  
  2726.     NAME
  2727.     SetMappingPropertiesA   -   set memory attributes in a memory map.
  2728.  
  2729.     SYNOPSIS
  2730.  
  2731.     result = SetMappingPropertiesA( list, flags, mask, lower, size, tags);
  2732.     d0                 a0     d1    d2    a1     d0    a2
  2733.  
  2734.     int SetMappingPropertiesA( struct MinList *, ULONG, ULONG, 
  2735.                    ULONG, ULONG, struct TagItem *);
  2736.  
  2737.  
  2738.     result = SetMappingProperties( list, flags, mask, 
  2739.                        lower, size, tag1, ...);
  2740.  
  2741.     int SetMappingProperties( struct MinList *, ULONG, ULONG, 
  2742.                   ULONG, ULONG, Tag tag1, ...);
  2743.  
  2744.     FUNCTION
  2745.     This call sets attributes of a certain memory range of a given
  2746.     memory map.
  2747.  
  2748.     INPUTS
  2749.     list    - a minlist structure keeping the memory map to be altered.
  2750.     flags   - a binary flags field for the attributes to define. Check
  2751.           SetProperties() for details about the defined bits.
  2752.     mask    - A bit mask of the attributes to be changed.
  2753.     lower   - The lower boundary of the logical address to be modified. 
  2754.     size    - Size of the region to be modified. 
  2755.     tags    - A tag array with additional data, identical to the
  2756.           tags defined for SetProperties().
  2757.  
  2758.     RESULTS
  2759.     Unlike SetProperties() or SetPageProperties(), this does not
  2760.     return a boolean value! The result code is 0 on failure, and
  2761.     different from zero on success, though. To be more precise, this
  2762.     routine will return "1" in case of success, and "2" in case the
  2763.     memory map was really altered and is now "dirty", hence upper
  2764.     software layers might require a "rebuild".
  2765.  
  2766.     NOTES
  2767.     This call really doesn't do anything to the MMU, it is just an
  2768.     administration call to modify a memory map - a handy data structure
  2769.     you might want to use for your own memory administration. Its
  2770.     context-based equivalent SetProperties() will, hence, adjust the
  2771.     memory map which is kept by a context, and SetPageProperties()
  2772.     will perform the same operation truely on the hardware.
  2773.  
  2774.     Since this call is not context based, the library will not be able
  2775.     to perform checks for correct page alignment, you have to do that
  2776.     yourself. Especially, note that SetPropertyList() - which attaches
  2777.     a memory map to a context - does not perform any check on this
  2778.     list either. Hence, *NOT* checking for page alignment here might
  2779.     result in an invalid context if you try to attach an incorrectly
  2780.     aligned list to a context later on. 
  2781.  
  2782.     BUGS
  2783.  
  2784.     SEE ALSO
  2785.     SetPropertyList(), ReleaseMapping(), SetProperties(),
  2786.     SetPageProperties(), GetMappingProperties()
  2787.  
  2788. mmu.library/GetMappingProperties      mmu.library/GetMappingProperties
  2789.  
  2790.     NAME
  2791.     GetMappingPropertiesA   - read memory attributes from a memory map.
  2792.  
  2793.     SYNOPSIS
  2794.  
  2795.     flags = GetMappingPropertiesA( list, lower, tags);
  2796.     d0                a0    a1     a2
  2797.  
  2798.     ULONG GetMappingPropertiesA( struct MinList *, ULONG, 
  2799.                      struct TagItem *);
  2800.  
  2801.     result = GetMappingProperties( list, lower, tag1, ...);
  2802.  
  2803.     ULONG GetMappingProperties( struct MinList *, ULONG, Tag tag1, ...);
  2804.  
  2805.     FUNCTION
  2806.     This call reads the page properties of a certain address in
  2807.     memory from a memory map. It is the counterpart of 
  2808.     SetMappingProperties() and the memory map analogue of 
  2809.     GetProperties().
  2810.  
  2811.     INPUTS
  2812.     list    -   a MinList holding the memory map, obtained from either
  2813.             GetMapping(), DupMapping() or NewMapping().
  2814.     lower   -   the logical address of the address to investigate. 
  2815.     tags    -   additional tags, identical to those defined for
  2816.             GetProperties(). Check the documentation of this
  2817.             function for details.
  2818.  
  2819.     RESULTS
  2820.     Returns a binary flags field for the attributes to define. See
  2821.     SetProperties() for details. 
  2822.  
  2823.     NOTES
  2824.     This call is the analogue of the GetProperties() call. It operates
  2825.     directly on memory maps, unlike the former which operates only on
  2826.     the memory map of a context. This function does not require page 
  2827.     alignment because the mmu.library does not have a context to check
  2828.     the alignment restrictions, but you should note that a memory map
  2829.     that is to be attached to a context with DefineMapping() *HAS* to
  2830.     be correctly aligned.
  2831.  
  2832.     This routine is *NOT* safe to be called from within interrupts.
  2833.  
  2834.     BUGS
  2835.  
  2836.     SEE ALSO
  2837.     SetMappingProperties(), SetProperties(), GetPageProperties(),
  2838.     GetProperties()
  2839.  
  2840. mmu.library/SetPropertyList            mmu.library/SetPropertyList
  2841.  
  2842.     NAME
  2843.     SetPropertyList     -   re-install a backup memory map
  2844.  
  2845.     SYNOPSIS
  2846.     SetPropertyList ( context, list );
  2847.                 a0      a1
  2848.  
  2849.     void SetPropertyList ( struct MMUContext * , struct MinList * );
  2850.  
  2851.     FUNCTION
  2852.     This call re-installes a property list, i.e. a complete memory
  2853.     map of a context, obtained from GetMapping() before.
  2854.     
  2855.     INPUTS
  2856.     context     -   the context the list should be installed in.
  2857.             This should be the same context the list was
  2858.             taken from.
  2859.     list    -   the property list to install. 
  2860.  
  2861.     This list *MUST* have been obtained with GetMapping() before.
  2862.  
  2863.     RESULTS
  2864.     Nothing. The big advantage of this call is that it cannot fail.
  2865.  
  2866.     NOTES
  2867.     The property list will become part of the context and is empty
  2868.     after this call. You can't re-use it for that reason. However,
  2869.     you still need to call ReleaseMapping() with the list pointer
  2870.     you've obtained before.
  2871.  
  2872.     For additional tips how this function should be used, see the
  2873.     GetMapping() function; especially, you can only un-do changes
  2874.     to the software abstraction level of a MMU-tree, and only as
  2875.     long as you haven't called RebuildTree() to translate these
  2876.     into hardware MMU tables. Trying to un-do these changes with
  2877.     SetPropertyList() will fail, and it will even fail if you call
  2878.     RebuildTree() afterwards. SetPropertyList() *does not* inform
  2879.     the software abstraction level about any changes, it is just a
  2880.     quick un-do operation. (For the experts: It even re-installs
  2881.     the "dirty" flags).
  2882.  
  2883.     BUGS
  2884.     
  2885.     SEE ALSO
  2886.     GetMapping(), ReleaseMapping(), RebuildTree()
  2887.  
  2888. mmu.library/GetMMUType                 mmu.library/GetMMUType
  2889.  
  2890.     NAME
  2891.     GetMMUType - return the type of the MMU available in the system.
  2892.  
  2893.     SYNOPSIS
  2894.     mmu = GetMMUType( );
  2895.             
  2896.  
  2897.     char GetMMUType( void );
  2898.  
  2899.     FUNCTION
  2900.     Returns an identifier for the MMU available in the system or
  2901.     NUL in case no MMU is installed.
  2902.  
  2903.     INPUTS
  2904.  
  2905.     RETURNS
  2906.     a character identifying the MMU type:
  2907.  
  2908.     MUTYPE_NONE        no working MMU detected.
  2909.     MUTYPE_68851        a 68020 system with an external 68851
  2910.                 MMU.
  2911.     MUTYPE_68030        a 68030 MMU.
  2912.     MUTYPE_68040        the internal 68040 MMU.
  2913.     MUTYPE_68060        the 68060 MMU.
  2914.  
  2915.     NOTES
  2916.     The mmu library is smart enough to detect EC processors without a
  2917.     working MMU, but the library does not detect multiple CPUs in the
  2918.     system. (How?)
  2919.  
  2920.     BUGS
  2921.  
  2922.     SEE ALSO
  2923.     mmu/mmubase.h
  2924. mmu.library/SuperContext               mmu.library/SuperContext
  2925.  
  2926.     NAME
  2927.     SuperContext - find the supervisor context for a given context.
  2928.  
  2929.     SYNOPSIS
  2930.     super = SuperContext( context );
  2931.     d0            a0              
  2932.  
  2933.     struct MMUContext * SuperContext( struct MMUContext * );
  2934.  
  2935.     FUNCTION
  2936.     Returns the context that manages the supervisor mode for the user
  2937.     mode context passed in.
  2938.  
  2939.     INPUTS
  2940.     A user mode context or NULL for the current context.
  2941.  
  2942.     RETURNS
  2943.     A pointer to the context managing the supervisor type accesses with-
  2944.     in the current context.
  2945.  
  2946.     NOTES
  2947.     All contexts build by CreateMMUContext are by default user mode
  2948.     contexts. The current version of the library manages one global
  2949.     supervisor tree, and optionally private supervisor trees for private
  2950.     contexts if you ask for one on context creation. This is different 
  2951.     to former releases!
  2952.     
  2953.     To find the public supervisor mode context, call DefaultContext() 
  2954.     first and pass in its return value to this function.
  2955.  
  2956.     BUGS
  2957.  
  2958.     SEE ALSO
  2959.     DefaultContext(), CreateMMUContext()
  2960.  
  2961. mmu.library/DefaultContext             mmu.library/DefaultContext
  2962.  
  2963.     NAME
  2964.     DefaultContext  -   get the global default context
  2965.  
  2966.     SYNOPSIS
  2967.     public = DefaultContext( );
  2968.     d0
  2969.  
  2970.     struct MMUContext * DefaultContext( void );
  2971.  
  2972.     FUNCTION
  2973.     Returns the global default user mode context which is used for
  2974.     tasks that are not attached to any other private context.
  2975.  
  2976.     INPUTS
  2977.  
  2978.     RETURNS
  2979.     A pointer to the context managing the user mode accesses for
  2980.     "context less" tasks.
  2981.  
  2982.     NOTES
  2983.     A task is by default part of this default context unless you
  2984.     call EnterMMUContext() and attach it to a different context.
  2985.  
  2986.     Note that you might have to enter even the default context
  2987.     explicitly to be able to use certain features of the exception
  2988.     hook mechanism.
  2989.  
  2990.     BUGS
  2991.  
  2992.     SEE ALSO
  2993.     SuperContext()
  2994. mmu.library/WithoutMMU                 mmu.library/WithoutMMU
  2995.  
  2996.     NAME
  2997.     WithoutMMU - execute a short subroutine with the MMU disabled.
  2998.  
  2999.     SYNOPSIS
  3000.     result = WithoutMMU( userFunc );
  3001.     d0            a5
  3002.  
  3003.     ULONG WithoutMMU(void *);
  3004.  
  3005.     FUNCTION
  3006.     Executes a small assembly language routine pointed to in a5
  3007.     in supervisor mode, with all interrupts disabled, and the MMU
  3008.     disabled. All registers are preserved by this call.
  3009.     The function must end with an RTS instruction.
  3010.  
  3011.     INPUTS
  3012.     userFunc    -   A pointer to a *short* assembly language routine,
  3013.             ending with RTS. The function has full access to
  3014.             all registers.
  3015.  
  3016.     RETURNS
  3017.     whatever was left in register d0 by the called function.
  3018.  
  3019.     NOTES
  3020.     This is a low-level function. Remember that disabling the MMU
  3021.     might or might not be what you want, especially if memory is
  3022.     remapped.
  3023.  
  3024.     Note that this function works even without a MMU. It just calls the
  3025.     routine in a5 in this case.
  3026.  
  3027.     BUGS
  3028.     Big trouble if the supervisor stack is in remapped memory.
  3029.  
  3030.     SEE ALSO
  3031.     exec/Supervisor(), RunOldConfig()
  3032. mmu.library/RunOldConfig                       mmu.library/RunOldConfig
  3033.  
  3034.     NAME
  3035.     RunOldConfig - execute a short subroutine with the old MMU configuration.   (V42)
  3036.  
  3037.     SYNOPSIS
  3038.     result = RunOldConfig( userFunc );
  3039.     d0              a5
  3040.  
  3041.     ULONG RunOldConfig(void *);
  3042.  
  3043.     FUNCTION
  3044.     Executes a small assembly language routine pointed to in a5
  3045.     in supervisor mode, with all interrupts disabled, and the MMU
  3046.     configuration the library found when it was started. This could 
  3047.     or could not be a disabled MMU.
  3048.     The function must end with an RTS instruction.
  3049.  
  3050.     INPUTS
  3051.     userFunc    -   A pointer to a *short* assembly language routine,
  3052.             ending with RTS. The function has full access to
  3053.             all registers.
  3054.  
  3055.     RETURNS
  3056.     whatever was left in register d0 by the called function.
  3057.  
  3058.     NOTES
  3059.     This is a low-level function. Remember that reloading the MMU
  3060.     with the last MMU configuration might or might not be what 
  3061.     you want, especially if memory is remapped or the MMU tables of
  3062.     the old configuration has been released.
  3063.  
  3064.     Note that this function works even without a MMU. It just calls the
  3065.     routine in a5 in this case.
  3066.  
  3067.     BUGS
  3068.     Big trouble if the supervisor stack is in remapped memory.
  3069.  
  3070.     SEE ALSO
  3071.     exec/Supervisor(), WithoutMMU()
  3072. mmu.library/SetBusError                mmu.library/SetBusError
  3073.  
  3074.     NAME
  3075.     SetBusError - define the bus error handler.
  3076.  
  3077.     SYNOPSIS
  3078.     SetBusError ( newfuncptr , oldfuncptrptr );
  3079.     d0        a0          a1
  3080.  
  3081.  
  3082.     void SetBusError ( void (*)() , void (**)() );
  3083.  
  3084.     FUNCTION
  3085.     This defines the bus error handler which is called in case the
  3086.     MMU library exception handler was not able to handle the fault.
  3087.  
  3088.     This happens for true physical bus errors, errors initiated by
  3089.     the unsupported TAS, CAS and CAS2 instructions using "locked
  3090.     transfers" not supported by the amiga hardware, and MOVE16 in-
  3091.     structions causing an access fault.
  3092.  
  3093.     The default bus error handler is whatever the library finds in
  3094.     the autovectors of the CPU when starting up. It is usually the
  3095.     exec fault handler which presents the nice guru 80000002.
  3096.  
  3097.     INPUTS
  3098.     newfuncptr    - A pointer to the new bus error handler. It is
  3099.             called without any parameters in supervisor state, 
  3100.             with the exception stack frame on the stack.
  3101.     oldfuncptrptr - A pointer to a pointer filled in with the previously
  3102.             defined handler, or NULL.
  3103.  
  3104.     RETURNS
  3105.  
  3106.     NOTES
  3107.     The function pointer is guaranteed to be flushed to memory by
  3108.     the library, the function pointer pointer could be used, for
  3109.     example, to modify the destination of a JMP instruction.
  3110.  
  3111.     The bus error handler *MUST BE IMMEDIATELY* ready for run after
  3112.     this function has to be called.
  3113.  
  3114.     This is a low-level function. You do not want to call it.
  3115.  
  3116.     BUGS
  3117.  
  3118.     SEE ALSO
  3119.  
  3120. mmu.library/GetMMUContextData          mmu.library/GetMMUContextData
  3121.  
  3122.     NAME
  3123.     GetMMUContextData - read MMUContext specific data
  3124.  
  3125.     SYNOPSIS
  3126.     GetMMUContextData ( ctx , id );
  3127.     d0            a0    d0
  3128.  
  3129.     ULONG GetMMUContextData ( struct MMUContext * , ULONG );
  3130.  
  3131.     FUNCTION
  3132.     This function reads various parameters of the MMU context,
  3133.     indexed by an ID from mmu/mmutags.h. All legal tag items
  3134.     of CreateMMContext() are available, plus the following:
  3135.  
  3136.         MGXTAG_PAGESIZE     -       Return the page size in bytes
  3137.                     of the input context. Unlike
  3138.                     MCXTAG_PAGEBITS, this is *NOT*
  3139.                     an exponent. This is identical
  3140.                     to GetPageSize().
  3141.  
  3142.         MGXTAG_REMAPSIZE    -       Returns the alignment restriction
  3143.                     for remapped memory to be added to
  3144.                     the exec memory free list. This is
  3145.                     identical to RemapSize().
  3146.  
  3147.         MGXTAG_ROOT        -       Return the pointer to the root of
  3148.                     the MMU tree. You have to cast the
  3149.                     result to an ULONG *. 
  3150.                     Note that you DO NOT WANT to modify 
  3151.                     this tree directly.
  3152.  
  3153.         MGXTAG_CONFIG       -       Returns the pointer to a 
  3154.                     struct MMUConfig * specifying the
  3155.                     complete MMU configuration for 
  3156.                     this context. You usually DO NOT
  3157.                     NEED to touch this.
  3158.  
  3159.     INPUTS
  3160.     ctx     -       A pointer to a struct MMUContext *.
  3161.  
  3162.     id      -       An ID specifying which data you want to read.
  3163.             NOTE THAT THIS IS NOT A TAG LIST, but just the
  3164.             tag item id from mmutags.h.
  3165.     RETURNS
  3166.     the data requested. You need to cast it to the correct type.
  3167.  
  3168.     NOTES
  3169.  
  3170.     BUGS
  3171.  
  3172.     SEE ALSO
  3173.     CreateMMUContext(), mmu/config.h
  3174.     
  3175. mmu.library/SetMMUContextData            mmu.library/SetMMUContextData
  3176.  
  3177.     NAME
  3178.     SetMMUContextData - define MMU context specifications on the fly
  3179.  
  3180.     SYNOPSIS
  3181.     SetMMUContextDataA ( ctx , tags );
  3182.                  a0    a1
  3183.  
  3184.     SetMMUContextData ( ctx , ... );
  3185.  
  3186.  
  3187.     void SetMMUContextDataA ( struct MMUContext * , struct TagItem * );
  3188.  
  3189.     void SetMMUContextData ( struct MMUContext * , Tag tag1 , ... );
  3190.  
  3191.     FUNCTION
  3192.     This function allows to adjust *some* of the MMUContext 
  3193.     specifications on the fly. The following tag items of the 
  3194.     CreateMMUContext() call are supported:
  3195.  
  3196.         MCXTAG_BLANKFILL    -       define the data to read from the
  3197.                     dummy "blank" pages. Note that
  3198.                     a *working* program should never
  3199.                     read this data.
  3200.  
  3201.         MCXTAG_EXECBASE     -       specify whether or not page 0 will
  3202.                     be threated specially and accesses
  3203.                     to the first Kbyte should be
  3204.                     emulated. If set to FALSE, the 
  3205.                     first page will be threated as all
  3206.                     other pages.
  3207.  
  3208.         MCXTAG_ZEROBASE     -       Specify a base address for where 
  3209.                     possibly emulated zero page accesses
  3210.                     have to be redirected to. This address
  3211.                     is usually ignored unless the zero-
  3212.                     page is invalidated and MCXTAG_EXEBASE
  3213.                     is TRUE. For the messy details, check
  3214.                     the CreateMMUContext() autodocs.
  3215.  
  3216.         MCXTAG_LOWMEMORYLIMIT -     Define the lower boundary of valid
  3217.                     memory, used to emulate access to the
  3218.                     zero page. Defaults to the lower 
  3219.                     boundary of chip memory. (V42)
  3220.  
  3221.     No other tag items are valid here.
  3222.  
  3223.     INPUTS
  3224.     ctx     -       A pointer to a struct MMUContext *.
  3225.  
  3226.     tags    -       A tag list containing the parameters to be
  3227.             adjusted.
  3228.     RETURNS
  3229.  
  3230.     NOTES
  3231.  
  3232.     BUGS
  3233.  
  3234.     SEE ALSO
  3235.     CreateMMUContext(), exec/memory.h
  3236.  
  3237. mmu.library/BuildIndirect              mmu.library/BuildIndirect
  3238.  
  3239.     NAME
  3240.     BuildIndirect       -   build a true hardware page descriptor.
  3241.  
  3242.     SYNOPSIS
  3243.     descr = BuildIndirect ( ctx , address , props );
  3244.     d0            a0      d0    d1
  3245.  
  3246.     ULONG   BuildIndirect ( struct MMUContext * , ULONG , ULONG );
  3247.  
  3248.     FUNCTION
  3249.     This function builds a true hardware page descriptor, to be used for
  3250.     the MAPP_INDIRECT property. 
  3251.  
  3252.     INPUTS
  3253.     ctx     -   the MMUContext handle in which this descriptor is to
  3254.             be used as the destination of a MAPP_INDIRECT descriptor.
  3255.  
  3256.     address -   in case this descriptor is "valid", this is the 
  3257.             PHYSICAL destination address, to be told to the MMU, to
  3258.             which accesses will be redirected to. Unlike 
  3259.             SetProperties(), there is *NO* MAPP_REMAPPED bit. In
  3260.             case you do not want remapping, set this to the logical
  3261.             address. DO NOT LEAVE THIS BLANK or accesses will be
  3262.             redirected to address 0 - which is most likely not want
  3263.             you want. Note that this address must be, as all other
  3264.             addresses the MMU cares about, page aligned!
  3265.             In case this descriptor is of invalid type, the address
  3266.             can be used for your purposes, but note that this MUST
  3267.             STILL be a number which is page aligned for the given
  3268.             context. It *MAY NOT* be arbitrary.
  3269.         
  3270.     props   -   Properties for the descriptor to be defined.
  3271.             NOTE THAT THIS IS A TRUE HARDWARE DESCRIPTOR! The
  3272.             library WILL NOT BE ABLE to help you out by emulating
  3273.             missing features of one MMU or another. Instead, it will
  3274.             just ignore them. This means for you, specifically, 
  3275.             that only a minor subset of the usual properties may be
  3276.             used safely here, and that parsing the hardware 
  3277.             properties later on with GetIndirect() might result in
  3278.             different properties than you intended because of
  3279.             missing features of the MMU in use. To be precise, the
  3280.             following properties *might* be available - meaning that
  3281.             all others ARE NOT!
  3282.  
  3283.         MAPP_WRITEPROTECTED  -  The page will be write protected. 
  3284.             Writes to this area will cause a segmentation fault.
  3285.  
  3286.         MAPP_USED         -   The "used" bit of the pages
  3287.             will be set. The CPU will set this bit automatically
  3288.             as soon as the pages are accessed.
  3289.  
  3290.         MAPP_MODIFIED         -   The "modified" bit of the pages
  3291.             will be set. The CPU will set this bit automatically
  3292.             as soon as a write is performed to the page in question.
  3293.             DO NOT SET THIS BIT TOGETHER WITH MAPP_WRITEPROTECTED
  3294.             OR WITHOUT MAPP_USED or the CPU might hang. 
  3295.  
  3296.         MAPP_INVALID         -   The page will be marked as 
  3297.             invalid. Accessing it will invoke the bus error hook.
  3298.             See below for how to mark this page as REMAIRABLE. Note
  3299.             that the MAPP_REPAIRABLE bit is *here* not available.
  3300.  
  3301.         MAPP_CACHEINHIBIT    -   The page will be marked as non-
  3302.             cacheable.
  3303.  
  3304.         MAPP_IMPRECISE         -   The page will be marked as 
  3305.             "imprecise exception". MAPP_CACHEINHIBIT is mandatory
  3306.             in this case or this flag does nothing. Only avail-
  3307.             able for the 060, ignored and read as zero 
  3308.             by all others.
  3309.  
  3310.         MAPP_NONSERIALIZED   -   The page will be marked as
  3311.             serialized. MAPP_CACHEINHIBIT is mandatory if this
  3312.             property is selected. Only available for the 040, 
  3313.             ignored and read as zero by all others.
  3314.  
  3315.         MAPP_COPYBACK         -   The page will be marked as
  3316.             "copyback" instead of "writethrough". Generally re-
  3317.             commended since this is faster for the '40 and '60.
  3318.             MAPP_CACHEINHIBIT *MUST* be disabled for this to work.
  3319.             Only available for the 040 and 060, ignored and read
  3320.             as zero by others.
  3321.  
  3322.         MAPP_USERPAGE0         -   Set user page attribute 0,
  3323.             only available for the 040 and 060, ignored and read
  3324.             as zero by all others.
  3325.             The status of this bit appears on special pins of the
  3326.             CPU and might be required by some hardware, so don't    
  3327.             play with this. 
  3328.  
  3329.         MAPP_USERPAGE1         -   Set user page attribute 1,
  3330.             see above for details.
  3331.  
  3332.         MAPP_GLOBAL         -   DIFFERENT TO SetProperties()
  3333.             and others! 
  3334.             Set the GLOBAL bit in the page descriptor, only avail-
  3335.             able for the 040 and 060, ignored and read as zero by
  3336.             all others. 
  3337.             Setting this bit means that certain specialized 
  3338.             instructions will not flush this descriptor from the
  3339.             cache (the ATC) of the MMU.
  3340.             The mmu.library writes only descriptors without this
  3341.             bit set and does not use these instructions. It will
  3342.             always flush descriptors independent of the G bit.
  3343.             There is little use of this bit.
  3344.  
  3345.     RESULTS
  3346.     a page descriptor for the current MMU in use, designed and to be
  3347.     used for as the destination of an MAPP_INDIRECT descriptor. NOT
  3348.     to be used as a true page descriptor, and NOT to be used as a 
  3349.     table descriptor.
  3350.     In case the library finds no MMU or the alignment restrictions 
  3351.     aren't satisfied, it will return BAD_DESCRIPTOR (0x03), it 
  3352.     WILL NOT return NULL as this is a "valid invalid" descriptor.
  3353.         
  3354.     NOTES
  3355.     Note specifically that MAPP_SUPERVISORONLY *IS NOT* supported. The
  3356.     mmu.library enforces a distinct user/supervisor model and as such
  3357.     you might want to install an invalid descriptor into the user table
  3358.     and a valid descriptor into the supervisor table to emulate this
  3359.     feature. True "supervisor only" descriptors are available for the
  3360.     040 and 060 anyways, but this "emulation" works for all MMUs.
  3361.  
  3362.     MAPP_REMAPPED is not supported either because you have to specify
  3363.     a physical destination address in all cases, even if no remapping
  3364.     has to be performed. Use the logical address as physical address in
  3365.     case remapping is not desired.
  3366.  
  3367.     MAPP_REPAIRABLE is not available because this flag is in fact an
  3368.     emulation provided by the library. However, you may make access 
  3369.     faults to this page repairable by setting the MAPP_REPAIRABLE bit
  3370.     for the MAPP_INDIRECT descriptor that POINTS to the descriptor 
  3371.     you're building by this call. This will be enough to inform the
  3372.     library about how to treat access faults.
  3373.     
  3374.  
  3375.     How to use this function:
  3376.  
  3377.     Allocate four bytes of memory, long-word aligned, or even 16 bytes 
  3378.     line (16 byte) aligned in case you want to read back the descriptor 
  3379.     later by GetIndirect() and calculate its TRUE PHYSICAL location with 
  3380.     PhysicalLocation(). Use the return code of this function to mask in
  3381.     your properties, DO NOT ASSUME fixed properties. Build a descriptor 
  3382.     with BuildIndirect() and install it into this memory by calling 
  3383.     SetIndirect(). *DO NOT* write it to the memory yourself! 
  3384.     Due to CPU caching effects, this must be done by the library. 
  3385.     Then build a MAPP_INDIRECT descriptor, and tell the library with the
  3386.     MAPTAG_DESCRIPTOR tag of SetProperties() to make it point to your
  3387.     memory. In case you want access faults on this to be repairable,
  3388.     set the MAPP_REPAIRABLE bit for this call. In case you want it write 
  3389.     protected but want to ignore write accesses, set MAPP_ROM, too. Then
  3390.     call RebuildTree() as usual. In case you want to exchange descriptors
  3391.     really fast - this is after all what indirect descriptors are 
  3392.     designed for - build all descriptors you require in a first step
  3393.     and keep them. A single call to SetIndirect() will exchange them
  3394.     VERY RAPIDLY which is ideal for certain applications. 
  3395.     
  3396.     BUGS
  3397.     Much more must be said about this function. It is definitely an
  3398.     advanced feature, so don't play with this in case you don't know
  3399.     what it does.
  3400.  
  3401.     SEE ALSO
  3402.     SetIndirect(), SetIndirectArray(), GetIndirect()
  3403.  
  3404. mmu.library/SetIndirect                mmu.library/SetIndirect
  3405.  
  3406.     NAME
  3407.     SetIndirect     -   Write a page descritor to memory
  3408.  
  3409.     SYNOPSIS
  3410.     SetIndirect ( destination , logical , descriptor );
  3411.             a0          a1      d0
  3412.  
  3413.     void SetIndirect ( ULONG *, ULONG, ULONG );
  3414.  
  3415.     FUNCTION
  3416.     Write a page descriptor, used as the destination of one or
  3417.     several MAPP_INDIRECT descriptors, out to memory and make the MMU
  3418.     aware of the change.
  3419.  
  3420.     INPUTS
  3421.     destination     -   the memory location to which the descriptor
  3422.                 should be written to. This is the same address
  3423.                 specified by MAPTAD_DESCRIPTOR in the corresponding
  3424.                 SetProperties() call. NOTE THAT THIS IS A 
  3425.                 PHYSICAL, NOT A LOGICAL ADDRESS.
  3426.                 This must be long-word aligned, or even 16 bytes 
  3427.                 line-aligned (16 bytes aligned) in case you want 
  3428.                 to read the descriptor later with GetIndirect().
  3429.  
  3430.     logical         -   The logical address covered by this descriptor, 
  3431.                 i.e. the address of the page which this 
  3432.                 descriptor is managing. In case you installed
  3433.                 the same descriptor for several logical addresses,
  3434.                 specify -1L (this will be slower, though.)
  3435.  
  3436.     descriptor      -   The descriptor to install.
  3437.  
  3438.     RESULTS
  3439.     doesn't return a result.
  3440.  
  3441.     NOTES
  3442.     Do NOT try to install a descriptor yourself, even though this 
  3443.     *seems* to be more effective. Somewhat more must be done than just
  3444.     writing the descriptor to memory. This call ensures that the
  3445.     descriptor is really written out to memory, and really fetched by
  3446.     the MMU. Specifying -1L as logical address is possible and supported
  3447.     but *slightly* less efficient than giving the correct 
  3448.     logical address.
  3449.     This call DOES NOT ensure that all data in the page to be modified
  3450.     is really written out. Hence, if you change the cache mode, the
  3451.     protection status or the validity status of a page, you should call
  3452.     CacheClearU() or CacheClearE() before. This step is, however, not
  3453.     required required in case you just changed the physical destination.
  3454.     The library keeps then care about the necessary cache operations
  3455.     itself.
  3456.  
  3457.     This call is *very* effective, there is little reason to try this
  3458.     yourself, not counting the portability problems.
  3459.  
  3460.     In case you want to install more than about four descriptors at once,
  3461.     you should consider using SetIndirectArray() which causes even less 
  3462.     overhead in this situation.
  3463.  
  3464.     BUGS
  3465.  
  3466.     SEE ALSO
  3467.     SetIndirectArray(), GetIndirect(), BuildIndirect()
  3468.  
  3469. mmu.library/SetIndirectArray           mmu.library/SetIndirectArray
  3470.  
  3471.     NAME
  3472.     SetIndirectArray    -   Write multiple page descritors to memory
  3473.  
  3474.     SYNOPSIS
  3475.     SetIndirectArray ( destination , descriptors , number );
  3476.                 a0      a1        d0
  3477.  
  3478.     void SetIndirectArray ( ULONG *, ULONG *, ULONG );
  3479.  
  3480.     FUNCTION
  3481.     Write a complete array of page descriptors at once, re-defining
  3482.     the mapping for more than one page, and make the MMU aware of the
  3483.     changes.
  3484.  
  3485.     INPUTS
  3486.     destination     -   an array in memory which keeps the true hardware
  3487.                 MMU descriptors. This address, and all subsequent
  3488.                 addresses must have been used in the corresponding
  3489.                 SetProperties() call to setup the descriptor.
  3490.                 NOTE THAT THIS IS A PHYSICAL ADDRESS. Note further
  3491.                 that it is up to you to ensure that the 
  3492.                 (obviously continuous) array of logical addresses
  3493.                 is not fragmentated into several physical memory
  3494.                 blocks. If this happens, you would have to call
  3495.                 this routine several times, once for each dis-
  3496.                 continuous block.
  3497.                 This must be long-word aligned, or even a multiple
  3498.                 of a 16 byte line-aligned array in case you want
  3499.                 to read the descriptor later with GetIndirect().
  3500.  
  3501.     descriptors     -   An array of pre-calculated descriptor values to be
  3502.                 filled in. This is a logical address. Effectively,
  3503.                 this call copies this array to its first argument.
  3504.  
  3505.     number          -   The number of the descriptors to be defined. Zero
  3506.                 is allowed here, and is a no-op.
  3507.  
  3508.     RESULTS
  3509.     doesn't return a result.
  3510.  
  3511.     NOTES
  3512.     Do NOT try to install descriptors yourself, even though this 
  3513.     *seems* to be more effective. Somewhat more must be done than just
  3514.     writing the descriptors to memory. This call ensures that the
  3515.     descriptors are really written out to memory, and really fetched by
  3516.     the MMU. Note that this call does not require the logical address
  3517.     of the page(s) which are about to be changed, quite different to
  3518.     SetIndirect(). It will be therefore slower than SetIndirect() if
  3519.     only very descriptors are to be written.
  3520.     This call DOES NOT ensure that all data in the page(s) to be modified
  3521.     is really written out. Hence, if you change the cache mode, the
  3522.     protection status or the validity status of a page, you should call
  3523.     CacheClearU() or CacheClearE() before. 
  3524.     This step is not required in case you just change the physical
  3525.     destination of the pages involved, the library is able to handle
  3526.     this transparently.
  3527.  
  3528.     This call is *very* effective, there is little reason to try this
  3529.     yourself, not counting the portability problems.
  3530.  
  3531.     If you install only one descriptor, SetIndirect() is more effective.
  3532.     Note further that this call does not require the logical address of
  3533.     the page(s) to be provided, it will flush the complete ATC of the
  3534.     MMU and is therefore slower if only a few pages or even a single page
  3535.     has to be modified. 
  3536.  
  3537.     BUGS
  3538.  
  3539.     SEE ALSO
  3540.     SetIndirect(), GetIndirect(), BuildIndirect()
  3541.  
  3542. mmu.library/GetIndirect                mmu.library/GetIndirect
  3543.  
  3544.     NAME
  3545.     GetIndirect     -   Read a hardware page descritor from memory
  3546.  
  3547.     SYNOPSIS
  3548.     GetIndirect ( ctx , adt , address );
  3549.               a0    a1      d0
  3550.  
  3551.     void GetIndirect ( struct MMUContext *, 
  3552.                struct AbstractDescriptor *, ULONG * );
  3553.  
  3554.     FUNCTION
  3555.     Reads a true hardware page descriptor, used as the destination 
  3556.     of one or several MAPP_INDIRECT descriptors, and places its data
  3557.     in the AbstractDescriptor structure.
  3558.  
  3559.     INPUTS
  3560.     ctx        -   the MMU context handle this page descriptor
  3561.                 belongs.
  3562.     adt        -   An abstract table descriptor, to be filled
  3563.                 out with the descriptor data.
  3564.     address         -   the address from where the descriptor is to 
  3565.                 be read. This is the same address which has been
  3566.                 passed as argument to the MAPTAG_DESCRIPTOR
  3567.                 tag of the SetProperties() call when building
  3568.                 the indirect descriptor.
  3569.                 All descriptors to be read by this function must
  3570.                 reside in a separate cache line, i.e. must be
  3571.                 part of a line (16 byte) aligned array which is a
  3572.                 multiple of 16 bytes long. In all other cases,
  3573.                 this call could return improper results due to
  3574.                 cache clashes.
  3575.     
  3576.     RESULTS
  3577.     no direct result code, but the AbstractDescriptor is filled
  3578.     in as follows:
  3579.  
  3580.     struct AbstractDescriptor {
  3581.         ULONG       atd_Pointer;
  3582.         ULONG       atd_Properties;
  3583.         UWORD       atd_LowerLimit;
  3584.         UWORD       atd_UpperLimit;
  3585.         UBYTE       atd_ThisType;
  3586.         UBYTE       atd_NextType;
  3587.         UWORD       atd_reserved;
  3588.     };
  3589.  
  3590.     atd_Pointer is either the physical address the accesses to the
  3591.     page(s) this descriptor is installed for are redirected to, or
  3592.     the user data if this descriptor is of invalid type. This is the
  3593.     same value that was passed in as "address" argument to the
  3594.     corresponding BuildIndirect() call.
  3595.  
  3596.     atd_Properties is the set of MMU properties read from the 
  3597.     descriptor. This NEED NOT to be identical to the properties setup
  3598.     by BuildIndirect(), for two reasons: First, the MMU sets the
  3599.     USED and MODIFIED attributes as soon as any access or a write
  3600.     access happens to the page(s) handled by the descriptor. Second,
  3601.     not all MMUs support all properties. Unavailable properties are
  3602.     ignored by BuildIndirect(), and read as zero by this function.
  3603.  
  3604.     All other fields are currently not documented and should not be
  3605.     read.
  3606.  
  3607.     NOTES
  3608.     Do NOT try to read a descriptor yourself, even though this 
  3609.     *seems* to be more effective. Somewhat more care must be kept for
  3610.     doing this. NOT following this rule might even lock up your
  3611.     machine!
  3612.  
  3613.     This call is *very* effective, there is little reason to try this
  3614.     yourself, not counting the portability problems.
  3615.  
  3616.     BUGS
  3617.  
  3618.     SEE ALSO
  3619.     SetIndirect(), BuildIndirect(), mmu/descriptor.h
  3620.